{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "36d40b101adfe75",
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-03-06T08:45:37.881012Z",
     "start_time": "2025-03-06T08:45:32.450235Z"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "\n",
    "sys.path.append(r'E:\\PycharmProjects\\risk-management')\n",
    "\n",
    "# 导入自定义模块，支持模型训练、预测、评估等功能\n",
    "from rmtools.utils import intnx\n",
    "import warnings\n",
    "\n",
    "import pandas as pd\n",
    "import statsmodels.api as sm\n",
    "import statsmodels.tsa.stattools as ts\n",
    "from sklearn.decomposition import PCA\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "from scipy.stats import chi2\n",
    "import numpy as np\n",
    "from rmtools.stats.stats import stats_max_corr, stats_max_vif\n",
    "from tqdm import tqdm\n",
    "\n",
    "# 调整pandas显示格式，保留两位小数，并使用千分位分隔符\n",
    "pd.options.display.float_format = '{:.2f}'.format\n",
    "\n",
    "warnings.filterwarnings(\"ignore\", category=FutureWarning)\n",
    "warnings.filterwarnings('ignore', category=UserWarning)\n",
    "\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "plt.rcParams['axes.unicode_minus'] = False"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 2024年度资本压力测试"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "1b00f39ce3552da4"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 模块1：各指标进行时间序列预测"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "d7136c781cf767a9"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# 前置一些常用模块\n",
    "def _gen_data(indata: pd.DataFrame | pd.Series, x: str | None = None) -> tuple[pd.DataFrame, str]:\n",
    "    if isinstance(indata, pd.DataFrame):\n",
    "        if x is None:\n",
    "            x = indata.columns[0]\n",
    "            warnings.warn(f\"输入变量未指明，默认使用第一列{x}\")\n",
    "        tsdata = indata.iloc[:, 0]\n",
    "    elif isinstance(indata, pd.Series):\n",
    "        tsdata = indata.copy()\n",
    "        x = indata.name\n",
    "    else:\n",
    "        raise ValueError(\"indata必须是pandas DataFrame或Series\")\n",
    "    return tsdata, x\n",
    "\n",
    "\n",
    "def draw_acf_pacf(indata: pd.DataFrame | pd.Series,\n",
    "                  x: str | None = None,\n",
    "                  label: str | None = None,\n",
    "                  size: int = 4,\n",
    "                  lags: int = 24) -> None:\n",
    "    \"\"\"\n",
    "    绘制自相关图（ACF）和偏自相关图（PACF）\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    indata: pd.DataFrame | pd.Series,\n",
    "        时间序列数据\n",
    "    x: str | None = None,\n",
    "        时间序列的列名\n",
    "    label: str | None = None,\n",
    "        图例标签\n",
    "    size: int = 4,\n",
    "        移动平均趋势图的滚动窗口大小\n",
    "    lags: int = 24,\n",
    "        自相关图的滞后阶数\n",
    "    \"\"\"\n",
    "    tsdata, x = _gen_data(indata, x)\n",
    "    label = x if label is None else label\n",
    "\n",
    "    rol_mean = tsdata.rolling(window=size).mean().fillna(0)\n",
    "    tsdiff = tsdata.diff(1).rolling(window=size).mean().fillna(0)\n",
    "    rol_diff = tsdiff.rolling(window=size).mean()\n",
    "\n",
    "    '''移动平均趋势图'''\n",
    "    f = plt.figure(figsize=(12, 8), facecolor='white')\n",
    "    ax1 = f.add_subplot(321)\n",
    "    tsdata.plot(color='blue', label='Original', ax=ax1)\n",
    "    rol_mean.plot(color='red', label='Rolling Mean', ls='dashed')\n",
    "    plt.title('The original / moving average plot of ' + label)\n",
    "    ax2 = f.add_subplot(322)\n",
    "    tsdiff.plot(color='blue', label='Original', ax=ax2)\n",
    "    rol_diff.plot(color='red', label='Rolling Mean', ls='dashed')\n",
    "    plt.title('The original / moving average plot of ' + label + '(1)')\n",
    "    '''自相关系数图'''\n",
    "    ax3 = f.add_subplot(323)\n",
    "    sm.graphics.tsa.plot_acf(tsdata, lags=lags, ax=ax3,\n",
    "                             title='The Autocorrelation plot of ' + label)\n",
    "    ax4 = f.add_subplot(324)\n",
    "    sm.graphics.tsa.plot_acf(tsdiff, lags=lags, ax=ax4,\n",
    "                             title='The Autocorrelation plot of ' + label + '(1)')\n",
    "    '''偏自相关图'''\n",
    "    ax5 = f.add_subplot(325)\n",
    "    sm.graphics.tsa.plot_pacf(tsdata, lags=lags, ax=ax5,\n",
    "                              title='The Partial Autocorrelation plot of ' + label)\n",
    "    ax6 = f.add_subplot(326)\n",
    "    sm.graphics.tsa.plot_pacf(tsdiff, lags=lags, ax=ax6,\n",
    "                              title='The Partial Autocorrelation plot of ' + label + '(1)')\n",
    "\n",
    "    plt.tight_layout()\n",
    "    plt.show()\n",
    "\n",
    "\n",
    "def stationarity_test(indata: pd.DataFrame | pd.Series, x: str | None = None) -> pd.DataFrame:\n",
    "    \"\"\"\n",
    "    测试时间序列的平稳性\n",
    "\n",
    "    Notes\n",
    "    -----\n",
    "    单位根 / 白噪声检验\n",
    "        a. 零均值、无趋势 x_t = a_1 * x_t-1 + ... + a_p * x_t-p + e_t\n",
    "        b. 有均值、无趋势 x_t = a_1 * x_t-1 + ... + a_p * x_t-p + a + e_t\n",
    "        c. 有均值、有趋势 x_t = a_1 * x_t-1 + ... + a_p * x_t-p + a + b * t + e_t\n",
    "        其中p为单位根检验中的最大滞后阶数\n",
    "\n",
    "    单位根检验是指检验序列中是否存在单位根，因为存在单位根就是非平稳时间序列了。单位根就是指单位根过程，可以证明，序列中存在单位根过程就不平稳，会使回归分析中存在伪回归。\n",
    "    迪基-福勒检验（Dickey-Fuller test）和扩展迪基-福勒检验（Augmented Dickey-Fuller test可以测试一个自回归模型是否存在单位根（unit root）。迪基-福勒检验模式是D.A迪基和W.A福勒建立的。\n",
    "    白噪声检验是指检验序列中是否存在白噪声，白噪声是指序列中没有明显的趋势或周期性。白噪声检验的目的在于判断序列是否具有随机性，如果序列具有随机性，则说明序列是平稳的。\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    indata: pd.DataFrame | pd.Series,\n",
    "        时间序列数据\n",
    "    x: str | None = None,\n",
    "        时间序列的列名\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    pd.DataFrame,\n",
    "        时间序列的平稳性检验结果\n",
    "    \"\"\"\n",
    "\n",
    "    def _test(data_: pd.DataFrame | pd.Series,\n",
    "              x_: str | None = None) -> pd.DataFrame:\n",
    "        tsdata, x_ = _gen_data(data_, x_)\n",
    "\n",
    "        reg = ['c', 'ct', 'ctt', 'n']\n",
    "        dfoutput = pd.DataFrame()\n",
    "\n",
    "        # 单位根检验\n",
    "        for i in reg:\n",
    "            dftest = ts.adfuller(tsdata, regression=i, maxlag=4)\n",
    "            dfresult = pd.DataFrame([dftest[0:4]],\n",
    "                                    columns=['Statistic', 'pValue', 'Lags', 'Nobs'],\n",
    "                                    index=[[x_], [i]])\n",
    "            dfoutput = pd.concat([dfoutput, dfresult])\n",
    "\n",
    "        # 白噪声检验\n",
    "        r, q, p = ts.acf(tsdata, qstat=True, nlags=12)\n",
    "        rst = pd.DataFrame([[1 + list(p).index(p.max()), p.max(), dfoutput['pValue'].min()]],\n",
    "                           index=[[x_], ['rst']],\n",
    "                           columns=['WNlag', 'Prob(>Q)', 'pValue'])\n",
    "\n",
    "        # 汇总检验结果\n",
    "        decimals = pd.Series([2, 4, 0, 0, 0, 4],\n",
    "                             index=['Statistic', 'pValue', 'Lags', 'Nobs', 'WNlag', 'Prob(>Q)'])\n",
    "        dfoutput = pd.concat([dfoutput, rst])\n",
    "        dfoutput.index.names = ['VarName', 'Type']\n",
    "        dfoutput['ADF单位根检验'] = 0 + (dfoutput['pValue'] < 0.05)\n",
    "        dfoutput['平稳性检验'] = dfoutput['pValue'].map(lambda y: '平稳' if y < 0.05 else '不平稳')\n",
    "        dfoutput['白噪声检验'] = dfoutput['Prob(>Q)'].map(lambda y: '白噪声' if y > 0.05 else '')\n",
    "        dfoutput = dfoutput.sort_index(level=[0, 1]).round(decimals)\n",
    "        return dfoutput\n",
    "\n",
    "    rst0 = _test(indata, x)\n",
    "    rst1 = _test(indata.diff(1).fillna(0), x)\n",
    "    rst1.index = [(i[0] + '(1)', i[1]) for i in rst1.index]\n",
    "    return pd.concat([rst0, rst1])\n",
    "\n",
    "\n",
    "def arima_pq(indata: pd.DataFrame | pd.Series,\n",
    "             x: str | None = None,\n",
    "             p_max: int = 4,\n",
    "             q_max: int = 4,\n",
    "             d: int = 0) -> pd.DataFrame:\n",
    "    ar_list = ['ar.L%s' % (x + 1) for x in range(p_max)]\n",
    "    ma_list = ['ma.L%s' % (x + 1) for x in range(q_max)]\n",
    "    dsn_summary = pd.DataFrame(columns=['p', 'd', 'q', 'aic', 'rank'] + ar_list + ma_list)\n",
    "\n",
    "    for p_iter in range(1, p_max + 1):\n",
    "        for q_iter in range(1, q_max + 1):\n",
    "            try:\n",
    "                model = sm.tsa.ARIMA(indata[x], order=(p_iter, d, q_iter))\n",
    "                results = model.fit()\n",
    "            except:\n",
    "                continue\n",
    "            dsn = pd.DataFrame(results.pvalues)\n",
    "            dsn.index = [x[:5] for x in dsn.index]\n",
    "            dsn = dsn.T\n",
    "            dsn['aic'] = results.aic\n",
    "            dsn[['p', 'd', 'q']] = [p_iter, d, q_iter]\n",
    "            dsn_summary = pd.concat([dsn_summary, dsn])\n",
    "    # dsn_summary['rank'] = dsn_summary['aic'].rank().astype('int')\n",
    "    # dsn_summary[ar_list + ma_list] = dsn_summary[ar_list + ma_list].round(2)\n",
    "\n",
    "    return dsn_summary"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:44:55.123533Z",
     "start_time": "2025-02-19T01:44:55.106961Z"
    }
   },
   "id": "e72b3e19a1da2e",
   "execution_count": 2
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 数据预处理"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "9ebf27f82329649f"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# 季末处理的指标清单\n",
    "x_qe_list: list = ['S0073300', 'M0012990', 'M0000541', 'M0000273']\n",
    "\n",
    "file_path = r'E:\\Psbc\\03.组合风险\\06.压力测试\\2024Q4\\信用风险\\\\中邮消费金融2024年信用风险压力测试工作底稿.xlsx'\n",
    "data_raw = pd.read_excel(file_path, sheet_name='原始数据', index_col=0)\n",
    "data_raw.index = pd.to_datetime(pd.to_datetime(data_raw.index).astype(str).map(lambda x: intnx(x, 'm', 0, 'e')))\n",
    "data_sample = data_raw.resample('QE').mean()\n",
    "data_sample[x_qe_list] = data_raw[x_qe_list].resample('QE').last()\n",
    "# 对数据进行向前填充，且只保留2010年之后的数据\n",
    "data_sample = data_sample.ffill().bfill().loc['2010-01-01':]\n",
    "# 删除指标NPL\n",
    "data_sample = data_sample.drop('NPL', axis=1)\n",
    "data_pca = (data_sample - data_sample.mean()) / data_sample.std()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:44:55.616039Z",
     "start_time": "2025-02-19T01:44:55.128307Z"
    }
   },
   "id": "f338f163dbf27b96",
   "execution_count": 3
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 球形检验"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "ce6b46061fdc0a3c"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "巴特利特球形检验统计量: 2379.196301272061\n",
      "自由度: 300.0\n",
      "p值: 0.0\n",
      "拒绝原假设，数据适合进行主成分分析。\n"
     ]
    }
   ],
   "source": [
    "# 步骤2: 计算相关矩阵\n",
    "correlation_matrix = np.corrcoef(data_pca, rowvar=False)\n",
    "n = data_pca.shape[0]  # 样本数量\n",
    "p = data_pca.shape[1]  # 变量数量\n",
    "# 计算检验统计量\n",
    "test_statistic = - (n - 1 - (2 * p + 5) / 6) * np.log(np.linalg.det(correlation_matrix))\n",
    "# 步骤4: 计算自由度\n",
    "degrees_of_freedom = p * (p - 1) / 2\n",
    "# 步骤5: 计算p值\n",
    "p_value = 1 - chi2.cdf(test_statistic, degrees_of_freedom)\n",
    "# 步骤6: 输出结果\n",
    "print(f\"巴特利特球形检验统计量: {test_statistic}\")\n",
    "print(f\"自由度: {degrees_of_freedom}\")\n",
    "print(f\"p值: {p_value}\")\n",
    "# 步骤7: 判断是否适合进行主成分分析\n",
    "if p_value < 0.05:\n",
    "    print(\"拒绝原假设，数据适合进行主成分分析。\")\n",
    "else:\n",
    "    print(\"不能拒绝原假设，数据可能不适合进行主成分分析。\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:44:55.627768Z",
     "start_time": "2025-02-19T01:44:55.620018Z"
    }
   },
   "id": "47bb047f697c4370",
   "execution_count": 4
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 主成分分析"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "c47a812e0b8108ec"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 640x480 with 1 Axes>",
      "image/png": "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Mcbr9ZrHH3/cOBwOc+qpp4ach9zcXONwOMykSZOC226++WYzbdq0kM+Li4szy5YtM1988YVJT0+v833AyYpQAjTDb3/7W9OxY0eTm5trjDFm0aJFJikpyaxcudIMGTLEXHLJJce9XXI8ffv2NTNnzgxr37lz55qePXvW+95TTz1lhg4dGnz97rvvhtzyCPj222+Ny+Uyjz766HG/55tvvjGpqalmwIABZvPmzcHtXq/XeL1e4/f7jTHGrFixwkg6YZ8Yn89nKioqgscYY8xHH33UqEDz2GOPhXxmYWGhcblcZt26deYnP/mJmTlzptm9e7eRZL766itz3nnnmT179hhjjHniiSfM9OnTTU5OTvD4iooK89RTT5lNmzaZIUOGmNdee81s3Lgx2Ofk4MGD5q677jIJCQkmPj7ePPjgg2br1q0hNQRCyeuvv262bNliNm3aZNauXWv27dsXDCWLFy82AwYMMJ06dTLPPvtsnSB2xx13GEkhoeTUU081Z599trnxxhvNjTfeaAoLC01aWpr54osvCCVocwglQDMcPHiwTh+CH//4x0aSGTBgQL0hoCGNCSXz5s0zXbt2NVu2bAl5eL1e88Ybb5iMjAxjTHVLRJcuXcwVV1wRcvx3331nunXrZi688EKzZs0as3nz5jqfFXi89957pnfv3sblctVpwQj49NNPjSTj9Xob9TuXl5ebvXv3miNHjpiCggLz/PPPm/T09ODrwCM/P98cOHCgTouNMca4XC4zd+5cc80115hJkyaZRYsWGUmmqqrKbN261Rw6dMgsWrTIjB8/vs6xP/vZz+oNP7NmzTITJ040CQkJ5oILLjDbtm0z33zzjRk8eLCRZDIzM4MtHYFQkpiYaFJSUkxCQoKx2+3BEGSxWEyPHj3Mk08+We918emnnxqLxWL69+8fDCXr1q0zkszTTz9tHnvsMWOz2UxVVZVJT08nlKBNOnoDF0CjdenSRZdeeqkkafv27Xrqqae0aNEiXXPNNfrss89066236p577tHll18e0l8ioKysTE6ns973Aowx8nq9MsbI5XLVef/gwYM688wzQ7YVFRWpT58+2rt3r8rKyoJDW6dNmxbyuf/xH/+hzp076ze/+Y2GDh16wt/1jDPO0Lfffqs777xTF154Yb37FBYWSpIcDsdxP+ef//ynLrjgguDrffv2yel0hvQd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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pca = PCA()\n",
    "pca.fit(data_pca)\n",
    "plt.plot(pca.explained_variance_ratio_)\n",
    "plt.title('各主成分方差解释比例')\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:44:55.741522Z",
     "start_time": "2025-02-19T01:44:55.630764Z"
    }
   },
   "id": "707b132d87fea965",
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "array([[ 0.11027302,  0.09027082,  0.21874447,  0.23953872,  0.20160883,\n         0.22241835,  0.0599571 ,  0.05608153,  0.21040374,  0.26014909,\n         0.26711787, -0.15853859,  0.24611238,  0.23536462,  0.20023854,\n         0.19888485, -0.19143203,  0.06728913,  0.22011531,  0.21215021,\n         0.26813949,  0.26510239,  0.11989844,  0.10751129,  0.26610146],\n       [ 0.38886161,  0.15953817,  0.07032744,  0.10652122, -0.0023746 ,\n        -0.20936553,  0.37847431,  0.39471932, -0.17319049, -0.16185613,\n        -0.16825713,  0.12734562,  0.06938254,  0.109937  , -0.03011246,\n         0.17072143, -0.20890326, -0.25075291,  0.14693531, -0.01077303,\n        -0.17400467, -0.1627298 ,  0.2385812 ,  0.22867106, -0.14929745],\n       [ 0.09006698, -0.0353525 ,  0.1363861 , -0.27668705,  0.3418088 ,\n         0.15721429,  0.27535106,  0.2742825 ,  0.01621708,  0.17871325,\n         0.13003781, -0.08467442, -0.27623719, -0.25681665, -0.39454364,\n        -0.16972562,  0.16617077,  0.03437821,  0.09631211,  0.2001716 ,\n         0.08444185, -0.12020831,  0.18296727, -0.2839339 ,  0.07780161],\n       [ 0.18372956,  0.55641388,  0.353915  , -0.01301281,  0.02232965,\n         0.02458358, -0.01860217, -0.03671594,  0.01075916,  0.00562886,\n         0.07389807, -0.24482594, -0.13368285, -0.11473156, -0.01253386,\n         0.26921946, -0.0131072 , -0.05366662, -0.27731613, -0.34444117,\n         0.09396781, -0.06936066, -0.3371875 , -0.16950333, -0.06739847],\n       [ 0.11026731, -0.22916197, -0.13898593,  0.05648214, -0.22102082,\n         0.23707357,  0.30242829,  0.21933551, -0.07894429,  0.02432886,\n         0.03122948, -0.26831807, -0.03640569, -0.03995807, -0.11708025,\n        -0.25618068, -0.34810231,  0.37721725, -0.25414455, -0.21141492,\n         0.11392747,  0.10860252, -0.20504205,  0.25246003, -0.0532465 ]])"
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca = PCA(n_components=0.8)\n",
    "pca.fit(data_pca)  # 保留80%方差的主成分\n",
    "pca.components_  # 主成分的特征向量（载荷矩阵）"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:44:55.756362Z",
     "start_time": "2025-02-19T01:44:55.745687Z"
    }
   },
   "id": "e5b2453bee442e17",
   "execution_count": 6
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 获取主成分的结果数据"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "b758fd5310db2c88"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            comp_1  comp_2  comp_3  comp_4  comp_5\nDate                                              \n2010-03-31    9.12    1.37   -3.01   -0.50   -2.53\n2010-06-30    7.36    1.28   -2.11   -1.20   -1.63\n2010-09-30    5.73    0.70   -2.21   -1.84   -0.35\n2010-12-31    5.37    0.79   -1.92   -0.23   -0.87\n2011-03-31    5.36    0.90   -1.46   -0.55   -0.67\n2011-06-30    4.93    0.28   -1.12   -1.10    0.52\n2011-09-30    4.31    0.16   -1.17   -1.71    0.17\n2011-12-31    2.53   -0.95   -0.87   -1.62    0.75\n2012-03-31    2.00   -2.70   -0.98   -1.81    3.81\n2012-06-30    1.01   -1.66   -1.11   -1.20    1.40\n2012-09-30    0.88   -1.79   -1.41    0.10    0.98\n2012-12-31    1.50   -1.63   -0.77   -0.03    0.99\n2013-03-31    2.10   -0.18   -1.06    1.33   -0.18\n2013-06-30    1.46   -0.38   -1.36    1.68    0.04\n2013-09-30    1.65   -0.25   -1.22    1.58    0.00\n2013-12-31    1.53   -0.20   -0.81    1.35    0.21\n2014-03-31    0.64   -0.46   -0.91    0.73    1.93\n2014-06-30    0.36   -0.80   -0.77   -0.41    1.18\n2014-09-30   -0.18   -1.53   -0.45   -1.51    1.24\n2014-12-31   -0.70   -2.02   -0.31   -0.90    0.98\n2015-03-31   -1.18   -1.89   -0.55   -0.10    1.46\n2015-06-30   -1.31   -1.66   -0.44    0.82    1.13\n2015-09-30   -0.94   -1.38   -1.18    1.60    0.73\n2015-12-31   -0.75   -1.18   -1.03    1.79    0.31\n2016-03-31    0.12   -0.59   -1.15    3.05    0.60\n2016-06-30    0.19    0.26   -0.84    3.54   -0.76\n2016-09-30    0.24    1.14   -0.03    4.36   -1.21\n2016-12-31    0.34    1.54    0.31    2.49   -0.66\n2017-03-31    1.26    1.74    1.23    0.86   -0.84\n2017-06-30    0.75    1.45    1.53    1.01   -0.57\n2017-09-30    0.55    1.52    1.59    0.53   -0.23\n2017-12-31    0.18    1.72    1.93    0.06    0.19\n2018-03-31    0.63    1.64    1.88   -0.23    0.66\n2018-06-30    0.12    1.46    2.11    0.09    0.51\n2018-09-30   -0.15    1.74    1.75   -0.15    0.56\n2018-12-31   -0.85    1.62    1.78    0.37    1.37\n2019-03-31   -0.91    1.55    1.44    0.20    2.21\n2019-06-30   -1.07    2.01    1.24    0.50    1.91\n2019-09-30   -1.53    1.76    1.09    0.42    1.64\n2019-12-31   -1.44    1.89    0.60   -0.02    1.88\n2020-03-31   -8.65    7.22   -3.40   -1.31   -0.22\n2020-06-30   -4.65    2.60   -1.70   -0.53   -0.21\n2020-09-30   -2.70    2.09   -0.25   -0.35   -0.60\n2020-12-31   -1.47    1.24    1.76    0.07   -1.02\n2021-03-31    7.77   -2.28    6.31   -0.42   -1.54\n2021-06-30    2.70    0.45    4.35   -0.85   -0.81\n2021-09-30   -0.15    0.89    3.04   -1.12   -0.39\n2021-12-31   -1.32    1.25    2.63   -1.91   -0.38\n2022-03-31   -2.16    1.11    1.32   -2.18   -0.25\n2022-06-30   -5.10    0.37   -1.49   -2.40   -1.96\n2022-09-30   -3.48   -1.24   -1.17   -1.48   -1.59\n2022-12-31   -4.17   -1.52   -1.78   -0.93   -1.50\n2023-03-31   -3.08   -1.17   -0.93   -0.22   -1.01\n2023-06-30   -2.30   -2.90   -0.31    0.63   -1.05\n2023-09-30   -3.65   -2.16   -0.20    0.54   -0.88\n2023-12-31   -2.97   -2.26    0.34    0.37   -0.90\n2024-03-31   -3.36   -2.12    0.36   -0.14   -0.78\n2024-06-30   -4.01   -2.64    0.84   -0.32   -1.06\n2024-09-30   -4.49   -2.80    0.85   -0.76   -1.21\n2024-12-31   -3.95   -3.40    1.19   -0.04   -1.50",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>comp_1</th>\n      <th>comp_2</th>\n      <th>comp_3</th>\n      <th>comp_4</th>\n      <th>comp_5</th>\n    </tr>\n    <tr>\n      <th>Date</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2010-03-31</th>\n      <td>9.12</td>\n      <td>1.37</td>\n      <td>-3.01</td>\n      <td>-0.50</td>\n      <td>-2.53</td>\n    </tr>\n    <tr>\n      <th>2010-06-30</th>\n      <td>7.36</td>\n      <td>1.28</td>\n      <td>-2.11</td>\n      <td>-1.20</td>\n      <td>-1.63</td>\n    </tr>\n    <tr>\n      <th>2010-09-30</th>\n      <td>5.73</td>\n      <td>0.70</td>\n      <td>-2.21</td>\n      <td>-1.84</td>\n      <td>-0.35</td>\n    </tr>\n    <tr>\n      <th>2010-12-31</th>\n      <td>5.37</td>\n      <td>0.79</td>\n      <td>-1.92</td>\n      <td>-0.23</td>\n      <td>-0.87</td>\n    </tr>\n    <tr>\n      <th>2011-03-31</th>\n      <td>5.36</td>\n      <td>0.90</td>\n      <td>-1.46</td>\n      <td>-0.55</td>\n      <td>-0.67</td>\n    </tr>\n    <tr>\n      <th>2011-06-30</th>\n      <td>4.93</td>\n      <td>0.28</td>\n      <td>-1.12</td>\n      <td>-1.10</td>\n      <td>0.52</td>\n    </tr>\n    <tr>\n      <th>2011-09-30</th>\n      <td>4.31</td>\n      <td>0.16</td>\n      <td>-1.17</td>\n      <td>-1.71</td>\n      <td>0.17</td>\n    </tr>\n    <tr>\n      <th>2011-12-31</th>\n      <td>2.53</td>\n      <td>-0.95</td>\n      <td>-0.87</td>\n      <td>-1.62</td>\n      <td>0.75</td>\n    </tr>\n    <tr>\n      <th>2012-03-31</th>\n      <td>2.00</td>\n      <td>-2.70</td>\n      <td>-0.98</td>\n      <td>-1.81</td>\n      <td>3.81</td>\n    </tr>\n    <tr>\n      <th>2012-06-30</th>\n      <td>1.01</td>\n      <td>-1.66</td>\n      <td>-1.11</td>\n      <td>-1.20</td>\n      <td>1.40</td>\n    </tr>\n    <tr>\n      <th>2012-09-30</th>\n      <td>0.88</td>\n      <td>-1.79</td>\n      <td>-1.41</td>\n      <td>0.10</td>\n      <td>0.98</td>\n    </tr>\n    <tr>\n      <th>2012-12-31</th>\n      <td>1.50</td>\n      <td>-1.63</td>\n      <td>-0.77</td>\n      <td>-0.03</td>\n      <td>0.99</td>\n    </tr>\n    <tr>\n      <th>2013-03-31</th>\n      <td>2.10</td>\n      <td>-0.18</td>\n      <td>-1.06</td>\n      <td>1.33</td>\n      <td>-0.18</td>\n    </tr>\n    <tr>\n      <th>2013-06-30</th>\n      <td>1.46</td>\n      <td>-0.38</td>\n      <td>-1.36</td>\n      <td>1.68</td>\n      <td>0.04</td>\n    </tr>\n    <tr>\n      <th>2013-09-30</th>\n      <td>1.65</td>\n      <td>-0.25</td>\n      <td>-1.22</td>\n      <td>1.58</td>\n      <td>0.00</td>\n    </tr>\n    <tr>\n      <th>2013-12-31</th>\n      <td>1.53</td>\n      <td>-0.20</td>\n      <td>-0.81</td>\n      <td>1.35</td>\n      <td>0.21</td>\n    </tr>\n    <tr>\n      <th>2014-03-31</th>\n      <td>0.64</td>\n      <td>-0.46</td>\n      <td>-0.91</td>\n      <td>0.73</td>\n      <td>1.93</td>\n    </tr>\n    <tr>\n      <th>2014-06-30</th>\n      <td>0.36</td>\n      <td>-0.80</td>\n      <td>-0.77</td>\n      <td>-0.41</td>\n      <td>1.18</td>\n    </tr>\n    <tr>\n      <th>2014-09-30</th>\n      <td>-0.18</td>\n      <td>-1.53</td>\n      <td>-0.45</td>\n      <td>-1.51</td>\n      <td>1.24</td>\n    </tr>\n    <tr>\n      <th>2014-12-31</th>\n      <td>-0.70</td>\n      <td>-2.02</td>\n      <td>-0.31</td>\n      <td>-0.90</td>\n      <td>0.98</td>\n    </tr>\n    <tr>\n      <th>2015-03-31</th>\n      <td>-1.18</td>\n      <td>-1.89</td>\n      <td>-0.55</td>\n      <td>-0.10</td>\n      <td>1.46</td>\n    </tr>\n    <tr>\n      <th>2015-06-30</th>\n      <td>-1.31</td>\n      <td>-1.66</td>\n      <td>-0.44</td>\n      <td>0.82</td>\n      <td>1.13</td>\n    </tr>\n    <tr>\n      <th>2015-09-30</th>\n      <td>-0.94</td>\n      <td>-1.38</td>\n      <td>-1.18</td>\n      <td>1.60</td>\n      <td>0.73</td>\n    </tr>\n    <tr>\n      <th>2015-12-31</th>\n      <td>-0.75</td>\n      <td>-1.18</td>\n      <td>-1.03</td>\n      <td>1.79</td>\n      <td>0.31</td>\n    </tr>\n    <tr>\n      <th>2016-03-31</th>\n      <td>0.12</td>\n      <td>-0.59</td>\n      <td>-1.15</td>\n      <td>3.05</td>\n      <td>0.60</td>\n    </tr>\n    <tr>\n      <th>2016-06-30</th>\n      <td>0.19</td>\n      <td>0.26</td>\n      <td>-0.84</td>\n      <td>3.54</td>\n      <td>-0.76</td>\n    </tr>\n    <tr>\n      <th>2016-09-30</th>\n      <td>0.24</td>\n      <td>1.14</td>\n      <td>-0.03</td>\n      <td>4.36</td>\n      <td>-1.21</td>\n    </tr>\n    <tr>\n      <th>2016-12-31</th>\n      <td>0.34</td>\n      <td>1.54</td>\n      <td>0.31</td>\n      <td>2.49</td>\n      <td>-0.66</td>\n    </tr>\n    <tr>\n      <th>2017-03-31</th>\n      <td>1.26</td>\n      <td>1.74</td>\n      <td>1.23</td>\n      <td>0.86</td>\n      <td>-0.84</td>\n    </tr>\n    <tr>\n      <th>2017-06-30</th>\n      <td>0.75</td>\n      <td>1.45</td>\n      <td>1.53</td>\n      <td>1.01</td>\n      <td>-0.57</td>\n    </tr>\n    <tr>\n      <th>2017-09-30</th>\n      <td>0.55</td>\n      <td>1.52</td>\n      <td>1.59</td>\n      <td>0.53</td>\n      <td>-0.23</td>\n    </tr>\n    <tr>\n      <th>2017-12-31</th>\n      <td>0.18</td>\n      <td>1.72</td>\n      <td>1.93</td>\n      <td>0.06</td>\n      <td>0.19</td>\n    </tr>\n    <tr>\n      <th>2018-03-31</th>\n      <td>0.63</td>\n      <td>1.64</td>\n      <td>1.88</td>\n      <td>-0.23</td>\n      <td>0.66</td>\n    </tr>\n    <tr>\n      <th>2018-06-30</th>\n      <td>0.12</td>\n      <td>1.46</td>\n      <td>2.11</td>\n      <td>0.09</td>\n      <td>0.51</td>\n    </tr>\n    <tr>\n      <th>2018-09-30</th>\n      <td>-0.15</td>\n      <td>1.74</td>\n      <td>1.75</td>\n      <td>-0.15</td>\n      <td>0.56</td>\n    </tr>\n    <tr>\n      <th>2018-12-31</th>\n      <td>-0.85</td>\n      <td>1.62</td>\n      <td>1.78</td>\n      <td>0.37</td>\n      <td>1.37</td>\n    </tr>\n    <tr>\n      <th>2019-03-31</th>\n      <td>-0.91</td>\n      <td>1.55</td>\n      <td>1.44</td>\n      <td>0.20</td>\n      <td>2.21</td>\n    </tr>\n    <tr>\n      <th>2019-06-30</th>\n      <td>-1.07</td>\n      <td>2.01</td>\n      <td>1.24</td>\n      <td>0.50</td>\n      <td>1.91</td>\n    </tr>\n    <tr>\n      <th>2019-09-30</th>\n      <td>-1.53</td>\n      <td>1.76</td>\n      <td>1.09</td>\n      <td>0.42</td>\n      <td>1.64</td>\n    </tr>\n    <tr>\n      <th>2019-12-31</th>\n      <td>-1.44</td>\n      <td>1.89</td>\n      <td>0.60</td>\n      <td>-0.02</td>\n      <td>1.88</td>\n    </tr>\n    <tr>\n      <th>2020-03-31</th>\n      <td>-8.65</td>\n      <td>7.22</td>\n      <td>-3.40</td>\n      <td>-1.31</td>\n      <td>-0.22</td>\n    </tr>\n    <tr>\n      <th>2020-06-30</th>\n      <td>-4.65</td>\n      <td>2.60</td>\n      <td>-1.70</td>\n      <td>-0.53</td>\n      <td>-0.21</td>\n    </tr>\n    <tr>\n      <th>2020-09-30</th>\n      <td>-2.70</td>\n      <td>2.09</td>\n      <td>-0.25</td>\n      <td>-0.35</td>\n      <td>-0.60</td>\n    </tr>\n    <tr>\n      <th>2020-12-31</th>\n      <td>-1.47</td>\n      <td>1.24</td>\n      <td>1.76</td>\n      <td>0.07</td>\n      <td>-1.02</td>\n    </tr>\n    <tr>\n      <th>2021-03-31</th>\n      <td>7.77</td>\n      <td>-2.28</td>\n      <td>6.31</td>\n      <td>-0.42</td>\n      <td>-1.54</td>\n    </tr>\n    <tr>\n      <th>2021-06-30</th>\n      <td>2.70</td>\n      <td>0.45</td>\n      <td>4.35</td>\n      <td>-0.85</td>\n      <td>-0.81</td>\n    </tr>\n    <tr>\n      <th>2021-09-30</th>\n      <td>-0.15</td>\n      <td>0.89</td>\n      <td>3.04</td>\n      <td>-1.12</td>\n      <td>-0.39</td>\n    </tr>\n    <tr>\n      <th>2021-12-31</th>\n      <td>-1.32</td>\n      <td>1.25</td>\n      <td>2.63</td>\n      <td>-1.91</td>\n      <td>-0.38</td>\n    </tr>\n    <tr>\n      <th>2022-03-31</th>\n      <td>-2.16</td>\n      <td>1.11</td>\n      <td>1.32</td>\n      <td>-2.18</td>\n      <td>-0.25</td>\n    </tr>\n    <tr>\n      <th>2022-06-30</th>\n      <td>-5.10</td>\n      <td>0.37</td>\n      <td>-1.49</td>\n      <td>-2.40</td>\n      <td>-1.96</td>\n    </tr>\n    <tr>\n      <th>2022-09-30</th>\n      <td>-3.48</td>\n      <td>-1.24</td>\n      <td>-1.17</td>\n      <td>-1.48</td>\n      <td>-1.59</td>\n    </tr>\n    <tr>\n      <th>2022-12-31</th>\n      <td>-4.17</td>\n      <td>-1.52</td>\n      <td>-1.78</td>\n      <td>-0.93</td>\n      <td>-1.50</td>\n    </tr>\n    <tr>\n      <th>2023-03-31</th>\n      <td>-3.08</td>\n      <td>-1.17</td>\n      <td>-0.93</td>\n      <td>-0.22</td>\n      <td>-1.01</td>\n    </tr>\n    <tr>\n      <th>2023-06-30</th>\n      <td>-2.30</td>\n      <td>-2.90</td>\n      <td>-0.31</td>\n      <td>0.63</td>\n      <td>-1.05</td>\n    </tr>\n    <tr>\n      <th>2023-09-30</th>\n      <td>-3.65</td>\n      <td>-2.16</td>\n      <td>-0.20</td>\n      <td>0.54</td>\n      <td>-0.88</td>\n    </tr>\n    <tr>\n      <th>2023-12-31</th>\n      <td>-2.97</td>\n      <td>-2.26</td>\n      <td>0.34</td>\n      <td>0.37</td>\n      <td>-0.90</td>\n    </tr>\n    <tr>\n      <th>2024-03-31</th>\n      <td>-3.36</td>\n      <td>-2.12</td>\n      <td>0.36</td>\n      <td>-0.14</td>\n      <td>-0.78</td>\n    </tr>\n    <tr>\n      <th>2024-06-30</th>\n      <td>-4.01</td>\n      <td>-2.64</td>\n      <td>0.84</td>\n      <td>-0.32</td>\n      <td>-1.06</td>\n    </tr>\n    <tr>\n      <th>2024-09-30</th>\n      <td>-4.49</td>\n      <td>-2.80</td>\n      <td>0.85</td>\n      <td>-0.76</td>\n      <td>-1.21</td>\n    </tr>\n    <tr>\n      <th>2024-12-31</th>\n      <td>-3.95</td>\n      <td>-3.40</td>\n      <td>1.19</td>\n      <td>-0.04</td>\n      <td>-1.50</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_pca_rst = pd.DataFrame(pca.transform(data_pca),\n",
    "                            columns=[f'comp_{i + 1}' for i in range(5)],\n",
    "                            index=data_pca.index)\n",
    "data_pca_rst"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:44:55.779460Z",
     "start_time": "2025-02-19T01:44:55.758346Z"
    }
   },
   "id": "862e3ad95f3343f8",
   "execution_count": 7
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 主成分的平稳性检验"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "c6f2929c61693872"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "               Statistic  pValue  Lags  Nobs  WNlag  Prob(>Q)  ADF单位根检验 平稳性检验  \\\ncomp_1    c        -2.52    0.11  4.00 55.00    NaN       NaN         0   不平稳   \n          ct       -3.74    0.02  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -3.54    0.10  4.00 55.00    NaN       NaN         0   不平稳   \n          n        -2.42    0.01  4.00 55.00    NaN       NaN         1    平稳   \n          rst        NaN    0.01   NaN   NaN   1.00      0.00         1    平稳   \ncomp_1(1) c        -5.43    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ct       -5.47    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -5.65    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          n        -5.68    0.00  3.00 56.00    NaN       NaN         1    平稳   \n          rst        NaN    0.00   NaN   NaN   3.00      0.58         1    平稳   \ncomp_2    c        -2.52    0.11  4.00 55.00    NaN       NaN         0   不平稳   \n          ct       -3.74    0.02  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -3.54    0.10  4.00 55.00    NaN       NaN         0   不平稳   \n          n        -2.42    0.01  4.00 55.00    NaN       NaN         1    平稳   \n          rst        NaN    0.01   NaN   NaN   1.00      0.00         1    平稳   \ncomp_2(1) c        -5.43    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ct       -5.47    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -5.65    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          n        -5.68    0.00  3.00 56.00    NaN       NaN         1    平稳   \n          rst        NaN    0.00   NaN   NaN   3.00      0.58         1    平稳   \ncomp_3    c        -2.52    0.11  4.00 55.00    NaN       NaN         0   不平稳   \n          ct       -3.74    0.02  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -3.54    0.10  4.00 55.00    NaN       NaN         0   不平稳   \n          n        -2.42    0.01  4.00 55.00    NaN       NaN         1    平稳   \n          rst        NaN    0.01   NaN   NaN   1.00      0.00         1    平稳   \ncomp_3(1) c        -5.43    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ct       -5.47    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -5.65    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          n        -5.68    0.00  3.00 56.00    NaN       NaN         1    平稳   \n          rst        NaN    0.00   NaN   NaN   3.00      0.58         1    平稳   \ncomp_4    c        -2.52    0.11  4.00 55.00    NaN       NaN         0   不平稳   \n          ct       -3.74    0.02  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -3.54    0.10  4.00 55.00    NaN       NaN         0   不平稳   \n          n        -2.42    0.01  4.00 55.00    NaN       NaN         1    平稳   \n          rst        NaN    0.01   NaN   NaN   1.00      0.00         1    平稳   \ncomp_4(1) c        -5.43    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ct       -5.47    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -5.65    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          n        -5.68    0.00  3.00 56.00    NaN       NaN         1    平稳   \n          rst        NaN    0.00   NaN   NaN   3.00      0.58         1    平稳   \ncomp_5    c        -2.52    0.11  4.00 55.00    NaN       NaN         0   不平稳   \n          ct       -3.74    0.02  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -3.54    0.10  4.00 55.00    NaN       NaN         0   不平稳   \n          n        -2.42    0.01  4.00 55.00    NaN       NaN         1    平稳   \n          rst        NaN    0.01   NaN   NaN   1.00      0.00         1    平稳   \ncomp_5(1) c        -5.43    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ct       -5.47    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          ctt      -5.65    0.00  4.00 55.00    NaN       NaN         1    平稳   \n          n        -5.68    0.00  3.00 56.00    NaN       NaN         1    平稳   \n          rst        NaN    0.00   NaN   NaN   3.00      0.58         1    平稳   \n\n              白噪声检验  \ncomp_1    c          \n          ct         \n          ctt        \n          n          \n          rst        \ncomp_1(1) c          \n          ct         \n          ctt        \n          n          \n          rst   白噪声  \ncomp_2    c          \n          ct         \n          ctt        \n          n          \n          rst        \ncomp_2(1) c          \n          ct         \n          ctt        \n          n          \n          rst   白噪声  \ncomp_3    c          \n          ct         \n          ctt        \n          n          \n          rst        \ncomp_3(1) c          \n          ct         \n          ctt        \n          n          \n          rst   白噪声  \ncomp_4    c          \n          ct         \n          ctt        \n          n          \n          rst        \ncomp_4(1) c          \n          ct         \n          ctt        \n          n          \n          rst   白噪声  \ncomp_5    c          \n          ct         \n          ctt        \n          n          \n          rst        \ncomp_5(1) c          \n          ct         \n          ctt        \n          n          \n          rst   白噪声  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>Statistic</th>\n      <th>pValue</th>\n      <th>Lags</th>\n      <th>Nobs</th>\n      <th>WNlag</th>\n      <th>Prob(&gt;Q)</th>\n      <th>ADF单位根检验</th>\n      <th>平稳性检验</th>\n      <th>白噪声检验</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_1</th>\n      <th>c</th>\n      <td>-2.52</td>\n      <td>0.11</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-3.74</td>\n      <td>0.02</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-3.54</td>\n      <td>0.10</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-2.42</td>\n      <td>0.01</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.01</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1.00</td>\n      <td>0.00</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_1(1)</th>\n      <th>c</th>\n      <td>-5.43</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-5.47</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-5.65</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-5.68</td>\n      <td>0.00</td>\n      <td>3.00</td>\n      <td>56.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>3.00</td>\n      <td>0.58</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td>白噪声</td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_2</th>\n      <th>c</th>\n      <td>-2.52</td>\n      <td>0.11</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-3.74</td>\n      <td>0.02</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-3.54</td>\n      <td>0.10</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-2.42</td>\n      <td>0.01</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.01</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1.00</td>\n      <td>0.00</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_2(1)</th>\n      <th>c</th>\n      <td>-5.43</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-5.47</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-5.65</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-5.68</td>\n      <td>0.00</td>\n      <td>3.00</td>\n      <td>56.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>3.00</td>\n      <td>0.58</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td>白噪声</td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_3</th>\n      <th>c</th>\n      <td>-2.52</td>\n      <td>0.11</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-3.74</td>\n      <td>0.02</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-3.54</td>\n      <td>0.10</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-2.42</td>\n      <td>0.01</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.01</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1.00</td>\n      <td>0.00</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_3(1)</th>\n      <th>c</th>\n      <td>-5.43</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-5.47</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-5.65</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-5.68</td>\n      <td>0.00</td>\n      <td>3.00</td>\n      <td>56.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>3.00</td>\n      <td>0.58</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td>白噪声</td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_4</th>\n      <th>c</th>\n      <td>-2.52</td>\n      <td>0.11</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-3.74</td>\n      <td>0.02</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-3.54</td>\n      <td>0.10</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-2.42</td>\n      <td>0.01</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.01</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1.00</td>\n      <td>0.00</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_4(1)</th>\n      <th>c</th>\n      <td>-5.43</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-5.47</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-5.65</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-5.68</td>\n      <td>0.00</td>\n      <td>3.00</td>\n      <td>56.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>3.00</td>\n      <td>0.58</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td>白噪声</td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_5</th>\n      <th>c</th>\n      <td>-2.52</td>\n      <td>0.11</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-3.74</td>\n      <td>0.02</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-3.54</td>\n      <td>0.10</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>0</td>\n      <td>不平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-2.42</td>\n      <td>0.01</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.01</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1.00</td>\n      <td>0.00</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th rowspan=\"5\" valign=\"top\">comp_5(1)</th>\n      <th>c</th>\n      <td>-5.43</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ct</th>\n      <td>-5.47</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>ctt</th>\n      <td>-5.65</td>\n      <td>0.00</td>\n      <td>4.00</td>\n      <td>55.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>n</th>\n      <td>-5.68</td>\n      <td>0.00</td>\n      <td>3.00</td>\n      <td>56.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td></td>\n    </tr>\n    <tr>\n      <th>rst</th>\n      <td>NaN</td>\n      <td>0.00</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>3.00</td>\n      <td>0.58</td>\n      <td>1</td>\n      <td>平稳</td>\n      <td>白噪声</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_comp = pd.DataFrame()\n",
    "for i in range(1, 6):\n",
    "    x = f'comp_{i}'\n",
    "    data_comp = pd.concat([data_comp, stationarity_test(data_pca_rst, x=x)])\n",
    "data_comp"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:44:55.920174Z",
     "start_time": "2025-02-19T01:44:55.785451Z"
    }
   },
   "id": "484137e507c9b945",
   "execution_count": 8
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 主成分的ARIMA模型定阶"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "856b63050fb4b692"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "data_comp = pd.DataFrame()\n",
    "for i in range(1, 6):\n",
    "    x = f'comp_{i}'\n",
    "    data_ = arima_pq(data_pca_rst, x=x)\n",
    "    # data_ = data_[data_['aic'] == data_['aic'].max()][['p', 'q', 'aic']]\n",
    "    data_['var'] = x\n",
    "    data_comp = pd.concat([data_comp, data_])"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:45:09.644910Z",
     "start_time": "2025-02-19T01:44:55.924164Z"
    }
   },
   "id": "765d9369017fb243",
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "data1 = sm.tsa.ARIMA(data_pca_rst['comp_1'], order=(2, 0, 1)).fit().get_forecast(steps=12).predicted_mean\n",
    "data2 = sm.tsa.ARIMA(data_pca_rst['comp_2'], order=(2, 0, 2)).fit().get_forecast(steps=12).predicted_mean\n",
    "data3 = sm.tsa.ARIMA(data_pca_rst['comp_3'], order=(3, 0, 2)).fit().get_forecast(steps=12).predicted_mean\n",
    "data4 = sm.tsa.ARIMA(data_pca_rst['comp_4'], order=(4, 0, 4)).fit().get_forecast(steps=12).predicted_mean\n",
    "data5 = sm.tsa.ARIMA(data_pca_rst['comp_5'], order=(4, 0, 4)).fit().get_forecast(steps=12).predicted_mean\n",
    "data_ = pd.concat([data1, data2, data3, data4, data5], axis=1)\n",
    "data_.columns = ['comp_1', 'comp_2', 'comp_3', 'comp_4', 'comp_5']"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:45:10.557809Z",
     "start_time": "2025-02-19T01:45:09.650397Z"
    }
   },
   "id": "faa601c71380395d",
   "execution_count": 10
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 主成分预测值反算"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "102cb44e22c7b2d2"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            S2707411  S2700453  S0073300  M0009970  M0041340  M0012990  \\\n2025-03-31     -1.61     -0.59     -0.70     -1.47     -0.08     -0.31   \n2025-06-30     -1.37     -0.64     -0.72     -1.20     -0.14     -0.34   \n2025-09-30     -1.32     -0.66     -0.72     -1.00     -0.20     -0.28   \n2025-12-31     -1.13     -0.64     -0.70     -0.79     -0.27     -0.27   \n2026-03-31     -1.02     -0.55     -0.62     -0.65     -0.31     -0.19   \n2026-06-30     -0.85     -0.42     -0.51     -0.54     -0.28     -0.17   \n2026-09-30     -0.72     -0.26     -0.37     -0.47     -0.25     -0.11   \n2026-12-31     -0.58     -0.12     -0.24     -0.40     -0.20     -0.08   \n2027-03-31     -0.48      0.03     -0.12     -0.35     -0.15     -0.05   \n2027-06-30     -0.39      0.09     -0.05     -0.30     -0.12     -0.02   \n2027-09-30     -0.34      0.14      0.00     -0.26     -0.09     -0.01   \n2027-12-31     -0.31      0.10     -0.00     -0.21     -0.06     -0.00   \n\n            M0012303  M0012304  M0024063  M0000541  ...  M0001383  M0000610  \\\n2025-03-31     -1.46     -1.38     -0.10     -0.28  ...     -1.05      1.89   \n2025-06-30     -1.20     -1.13     -0.13     -0.31  ...     -0.94      1.55   \n2025-09-30     -1.19     -1.13     -0.08     -0.27  ...     -0.85      1.36   \n2025-12-31     -1.01     -0.96     -0.10     -0.28  ...     -0.74      1.08   \n2026-03-31     -0.93     -0.90     -0.07     -0.24  ...     -0.65      0.89   \n2026-06-30     -0.80     -0.78     -0.06     -0.22  ...     -0.52      0.74   \n2026-09-30     -0.72     -0.71     -0.03     -0.17  ...     -0.41      0.64   \n2026-12-31     -0.61     -0.61     -0.02     -0.13  ...     -0.30      0.54   \n2027-03-31     -0.56     -0.57      0.00     -0.09  ...     -0.20      0.48   \n2027-06-30     -0.49     -0.49      0.01     -0.07  ...     -0.14      0.41   \n2027-09-30     -0.45     -0.45      0.03     -0.04  ...     -0.08      0.36   \n2027-12-31     -0.40     -0.40      0.04     -0.02  ...     -0.07      0.32   \n\n            M0000611  M0000609  M0000607  M0001428  M0000273  M0001227  \\\n2025-03-31      0.06     -0.74     -0.19     -0.49     -0.68     -0.64   \n2025-06-30      0.02     -0.54     -0.10     -0.50     -0.58     -0.43   \n2025-09-30      0.08     -0.50     -0.09     -0.42     -0.43     -0.43   \n2025-12-31      0.09     -0.43     -0.11     -0.40     -0.34     -0.37   \n2026-03-31      0.15     -0.46     -0.17     -0.30     -0.24     -0.44   \n2026-06-30      0.12     -0.42     -0.19     -0.26     -0.21     -0.41   \n2026-09-30      0.14     -0.45     -0.25     -0.17     -0.17     -0.46   \n2026-12-31      0.11     -0.44     -0.27     -0.12     -0.15     -0.46   \n2027-03-31      0.09     -0.44     -0.30     -0.07     -0.13     -0.48   \n2027-06-30      0.08     -0.40     -0.29     -0.03     -0.11     -0.45   \n2027-09-30      0.07     -0.37     -0.27     -0.00     -0.09     -0.43   \n2027-12-31      0.06     -0.29     -0.21      0.00     -0.06     -0.35   \n\n            M0000612  M0000545  \n2025-03-31     -1.62     -0.32  \n2025-06-30     -1.25     -0.31  \n2025-09-30     -1.05     -0.24  \n2025-12-31     -0.77     -0.24  \n2026-03-31     -0.64     -0.20  \n2026-06-30     -0.54     -0.19  \n2026-09-30     -0.51     -0.16  \n2026-12-31     -0.47     -0.14  \n2027-03-31     -0.47     -0.12  \n2027-06-30     -0.42     -0.10  \n2027-09-30     -0.40     -0.07  \n2027-12-31     -0.34     -0.04  \n\n[12 rows x 25 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>S2707411</th>\n      <th>S2700453</th>\n      <th>S0073300</th>\n      <th>M0009970</th>\n      <th>M0041340</th>\n      <th>M0012990</th>\n      <th>M0012303</th>\n      <th>M0012304</th>\n      <th>M0024063</th>\n      <th>M0000541</th>\n      <th>...</th>\n      <th>M0001383</th>\n      <th>M0000610</th>\n      <th>M0000611</th>\n      <th>M0000609</th>\n      <th>M0000607</th>\n      <th>M0001428</th>\n      <th>M0000273</th>\n      <th>M0001227</th>\n      <th>M0000612</th>\n      <th>M0000545</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2025-03-31</th>\n      <td>-1.61</td>\n      <td>-0.59</td>\n      <td>-0.70</td>\n      <td>-1.47</td>\n      <td>-0.08</td>\n      <td>-0.31</td>\n      <td>-1.46</td>\n      <td>-1.38</td>\n      <td>-0.10</td>\n      <td>-0.28</td>\n      <td>...</td>\n      <td>-1.05</td>\n      <td>1.89</td>\n      <td>0.06</td>\n      <td>-0.74</td>\n      <td>-0.19</td>\n      <td>-0.49</td>\n      <td>-0.68</td>\n      <td>-0.64</td>\n      <td>-1.62</td>\n      <td>-0.32</td>\n    </tr>\n    <tr>\n      <th>2025-06-30</th>\n      <td>-1.37</td>\n      <td>-0.64</td>\n      <td>-0.72</td>\n      <td>-1.20</td>\n      <td>-0.14</td>\n      <td>-0.34</td>\n      <td>-1.20</td>\n      <td>-1.13</td>\n      <td>-0.13</td>\n      <td>-0.31</td>\n      <td>...</td>\n      <td>-0.94</td>\n      <td>1.55</td>\n      <td>0.02</td>\n      <td>-0.54</td>\n      <td>-0.10</td>\n      <td>-0.50</td>\n      <td>-0.58</td>\n      <td>-0.43</td>\n      <td>-1.25</td>\n      <td>-0.31</td>\n    </tr>\n    <tr>\n      <th>2025-09-30</th>\n      <td>-1.32</td>\n      <td>-0.66</td>\n      <td>-0.72</td>\n      <td>-1.00</td>\n      <td>-0.20</td>\n      <td>-0.28</td>\n      <td>-1.19</td>\n      <td>-1.13</td>\n      <td>-0.08</td>\n      <td>-0.27</td>\n      <td>...</td>\n      <td>-0.85</td>\n      <td>1.36</td>\n      <td>0.08</td>\n      <td>-0.50</td>\n      <td>-0.09</td>\n      <td>-0.42</td>\n      <td>-0.43</td>\n      <td>-0.43</td>\n      <td>-1.05</td>\n      <td>-0.24</td>\n    </tr>\n    <tr>\n      <th>2025-12-31</th>\n      <td>-1.13</td>\n      <td>-0.64</td>\n      <td>-0.70</td>\n      <td>-0.79</td>\n      <td>-0.27</td>\n      <td>-0.27</td>\n      <td>-1.01</td>\n      <td>-0.96</td>\n      <td>-0.10</td>\n      <td>-0.28</td>\n      <td>...</td>\n      <td>-0.74</td>\n      <td>1.08</td>\n      <td>0.09</td>\n      <td>-0.43</td>\n      <td>-0.11</td>\n      <td>-0.40</td>\n      <td>-0.34</td>\n      <td>-0.37</td>\n      <td>-0.77</td>\n      <td>-0.24</td>\n    </tr>\n    <tr>\n      <th>2026-03-31</th>\n      <td>-1.02</td>\n      <td>-0.55</td>\n      <td>-0.62</td>\n      <td>-0.65</td>\n      <td>-0.31</td>\n      <td>-0.19</td>\n      <td>-0.93</td>\n      <td>-0.90</td>\n      <td>-0.07</td>\n      <td>-0.24</td>\n      <td>...</td>\n      <td>-0.65</td>\n      <td>0.89</td>\n      <td>0.15</td>\n      <td>-0.46</td>\n      <td>-0.17</td>\n      <td>-0.30</td>\n      <td>-0.24</td>\n      <td>-0.44</td>\n      <td>-0.64</td>\n      <td>-0.20</td>\n    </tr>\n    <tr>\n      <th>2026-06-30</th>\n      <td>-0.85</td>\n      <td>-0.42</td>\n      <td>-0.51</td>\n      <td>-0.54</td>\n      <td>-0.28</td>\n      <td>-0.17</td>\n      <td>-0.80</td>\n      <td>-0.78</td>\n      <td>-0.06</td>\n      <td>-0.22</td>\n      <td>...</td>\n      <td>-0.52</td>\n      <td>0.74</td>\n      <td>0.12</td>\n      <td>-0.42</td>\n      <td>-0.19</td>\n      <td>-0.26</td>\n      <td>-0.21</td>\n      <td>-0.41</td>\n      <td>-0.54</td>\n      <td>-0.19</td>\n    </tr>\n    <tr>\n      <th>2026-09-30</th>\n      <td>-0.72</td>\n      <td>-0.26</td>\n      <td>-0.37</td>\n      <td>-0.47</td>\n      <td>-0.25</td>\n      <td>-0.11</td>\n      <td>-0.72</td>\n      <td>-0.71</td>\n      <td>-0.03</td>\n      <td>-0.17</td>\n      <td>...</td>\n      <td>-0.41</td>\n      <td>0.64</td>\n      <td>0.14</td>\n      <td>-0.45</td>\n      <td>-0.25</td>\n      <td>-0.17</td>\n      <td>-0.17</td>\n      <td>-0.46</td>\n      <td>-0.51</td>\n      <td>-0.16</td>\n    </tr>\n    <tr>\n      <th>2026-12-31</th>\n      <td>-0.58</td>\n      <td>-0.12</td>\n      <td>-0.24</td>\n      <td>-0.40</td>\n      <td>-0.20</td>\n      <td>-0.08</td>\n      <td>-0.61</td>\n      <td>-0.61</td>\n      <td>-0.02</td>\n      <td>-0.13</td>\n      <td>...</td>\n      <td>-0.30</td>\n      <td>0.54</td>\n      <td>0.11</td>\n      <td>-0.44</td>\n      <td>-0.27</td>\n      <td>-0.12</td>\n      <td>-0.15</td>\n      <td>-0.46</td>\n      <td>-0.47</td>\n      <td>-0.14</td>\n    </tr>\n    <tr>\n      <th>2027-03-31</th>\n      <td>-0.48</td>\n      <td>0.03</td>\n      <td>-0.12</td>\n      <td>-0.35</td>\n      <td>-0.15</td>\n      <td>-0.05</td>\n      <td>-0.56</td>\n      <td>-0.57</td>\n      <td>0.00</td>\n      <td>-0.09</td>\n      <td>...</td>\n      <td>-0.20</td>\n      <td>0.48</td>\n      <td>0.09</td>\n      <td>-0.44</td>\n      <td>-0.30</td>\n      <td>-0.07</td>\n      <td>-0.13</td>\n      <td>-0.48</td>\n      <td>-0.47</td>\n      <td>-0.12</td>\n    </tr>\n    <tr>\n      <th>2027-06-30</th>\n      <td>-0.39</td>\n      <td>0.09</td>\n      <td>-0.05</td>\n      <td>-0.30</td>\n      <td>-0.12</td>\n      <td>-0.02</td>\n      <td>-0.49</td>\n      <td>-0.49</td>\n      <td>0.01</td>\n      <td>-0.07</td>\n      <td>...</td>\n      <td>-0.14</td>\n      <td>0.41</td>\n      <td>0.08</td>\n      <td>-0.40</td>\n      <td>-0.29</td>\n      <td>-0.03</td>\n      <td>-0.11</td>\n      <td>-0.45</td>\n      <td>-0.42</td>\n      <td>-0.10</td>\n    </tr>\n    <tr>\n      <th>2027-09-30</th>\n      <td>-0.34</td>\n      <td>0.14</td>\n      <td>0.00</td>\n      <td>-0.26</td>\n      <td>-0.09</td>\n      <td>-0.01</td>\n      <td>-0.45</td>\n      <td>-0.45</td>\n      <td>0.03</td>\n      <td>-0.04</td>\n      <td>...</td>\n      <td>-0.08</td>\n      <td>0.36</td>\n      <td>0.07</td>\n      <td>-0.37</td>\n      <td>-0.27</td>\n      <td>-0.00</td>\n      <td>-0.09</td>\n      <td>-0.43</td>\n      <td>-0.40</td>\n      <td>-0.07</td>\n    </tr>\n    <tr>\n      <th>2027-12-31</th>\n      <td>-0.31</td>\n      <td>0.10</td>\n      <td>-0.00</td>\n      <td>-0.21</td>\n      <td>-0.06</td>\n      <td>-0.00</td>\n      <td>-0.40</td>\n      <td>-0.40</td>\n      <td>0.04</td>\n      <td>-0.02</td>\n      <td>...</td>\n      <td>-0.07</td>\n      <td>0.32</td>\n      <td>0.06</td>\n      <td>-0.29</td>\n      <td>-0.21</td>\n      <td>0.00</td>\n      <td>-0.06</td>\n      <td>-0.35</td>\n      <td>-0.34</td>\n      <td>-0.04</td>\n    </tr>\n  </tbody>\n</table>\n<p>12 rows × 25 columns</p>\n</div>"
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_inv = pca.inverse_transform(data_)\n",
    "data_inv.columns = data_sample.columns\n",
    "data_inv"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:45:10.575328Z",
     "start_time": "2025-02-19T01:45:10.559797Z"
    }
   },
   "id": "36ec108ea3b9e4bf",
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            S2707411  S2700453  S0073300  M0009970  M0041340  M0012990  \\\n2025-03-31     -4.51      0.08     -7.95      9.43     99.02      5.05   \n2025-06-30     -3.36      0.05     -8.38     10.20     98.79      4.97   \n2025-09-30     -3.13      0.04     -8.32     10.78     98.52      5.14   \n2025-12-31     -2.20      0.05     -8.00     11.40     98.21      5.17   \n2026-03-31     -1.66      0.09     -6.64     11.81     98.06      5.39   \n2026-06-30     -0.85      0.16     -4.68     12.14     98.16      5.43   \n2026-09-30     -0.23      0.24     -2.22     12.34     98.31      5.62   \n2026-12-31      0.45      0.30     -0.12     12.53     98.50      5.70   \n2027-03-31      0.92      0.38      2.09     12.67     98.72      5.79   \n2027-06-30      1.35      0.41      3.21     12.82     98.85      5.86   \n2027-09-30      1.62      0.43      4.15     12.95     98.99      5.90   \n2027-12-31      1.77      0.41      4.08     13.08     99.09      5.92   \n\n            M0012303  M0012304  M0024063  M0000541  ...  M0001383  M0000610  \\\n2025-03-31     89.03     87.13      7.58      5.87  ...      0.45    856.76   \n2025-06-30     92.15     89.97      7.12      5.77  ...      1.33    778.11   \n2025-09-30     92.32     89.99      7.80      5.92  ...      2.00    730.91   \n2025-12-31     94.49     91.84      7.54      5.87  ...      2.87    664.13   \n2026-03-31     95.43     92.48      7.93      6.02  ...      3.59    620.02   \n2026-06-30     96.94     93.82      8.00      6.09  ...      4.65    585.41   \n2026-09-30     97.96     94.61      8.36      6.28  ...      5.52    559.35   \n2026-12-31     99.25     95.74      8.50      6.39  ...      6.37    536.12   \n2027-03-31     99.84     96.26      8.85      6.53  ...      7.22    523.14   \n2027-06-30    100.79     97.09      8.97      6.62  ...      7.71    505.16   \n2027-09-30    101.24     97.51      9.21      6.72  ...      8.15    494.70   \n2027-12-31    101.79     98.06      9.33      6.78  ...      8.27    484.11   \n\n            M0000611  M0000609  M0000607  M0001428  M0000273  M0001227  \\\n2025-03-31     49.74     -3.92      6.08      6.04      5.44     -1.89   \n2025-06-30     42.75     -0.81      7.38      5.94      6.26     -0.96   \n2025-09-30     53.75     -0.07      7.53      6.54      7.62     -0.97   \n2025-12-31     54.73      1.01      7.34      6.71      8.40     -0.69   \n2026-03-31     65.94      0.53      6.42      7.39      9.27     -0.98   \n2026-06-30     59.85      1.21      6.18      7.69      9.56     -0.85   \n2026-09-30     63.08      0.68      5.28      8.32      9.92     -1.11   \n2026-12-31     59.12      0.95      4.96      8.69     10.06     -1.07   \n2027-03-31     55.55      0.95      4.57      9.10     10.22     -1.17   \n2027-06-30     53.97      1.45      4.67      9.35     10.41     -1.05   \n2027-09-30     51.70      2.01      4.93      9.57     10.62     -0.95   \n2027-12-31     49.79      3.23      5.86      9.62     10.86     -0.60   \n\n            M0000612  M0000545  \n2025-03-31     -0.18      6.08  \n2025-06-30      0.35      6.15  \n2025-09-30      0.63      6.50  \n2025-12-31      1.03      6.52  \n2026-03-31      1.21      6.70  \n2026-06-30      1.36      6.78  \n2026-09-30      1.40      6.92  \n2026-12-31      1.46      7.00  \n2027-03-31      1.46      7.13  \n2027-06-30      1.52      7.23  \n2027-09-30      1.56      7.37  \n2027-12-31      1.64      7.51  \n\n[12 rows x 25 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>S2707411</th>\n      <th>S2700453</th>\n      <th>S0073300</th>\n      <th>M0009970</th>\n      <th>M0041340</th>\n      <th>M0012990</th>\n      <th>M0012303</th>\n      <th>M0012304</th>\n      <th>M0024063</th>\n      <th>M0000541</th>\n      <th>...</th>\n      <th>M0001383</th>\n      <th>M0000610</th>\n      <th>M0000611</th>\n      <th>M0000609</th>\n      <th>M0000607</th>\n      <th>M0001428</th>\n      <th>M0000273</th>\n      <th>M0001227</th>\n      <th>M0000612</th>\n      <th>M0000545</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2025-03-31</th>\n      <td>-4.51</td>\n      <td>0.08</td>\n      <td>-7.95</td>\n      <td>9.43</td>\n      <td>99.02</td>\n      <td>5.05</td>\n      <td>89.03</td>\n      <td>87.13</td>\n      <td>7.58</td>\n      <td>5.87</td>\n      <td>...</td>\n      <td>0.45</td>\n      <td>856.76</td>\n      <td>49.74</td>\n      <td>-3.92</td>\n      <td>6.08</td>\n      <td>6.04</td>\n      <td>5.44</td>\n      <td>-1.89</td>\n      <td>-0.18</td>\n      <td>6.08</td>\n    </tr>\n    <tr>\n      <th>2025-06-30</th>\n      <td>-3.36</td>\n      <td>0.05</td>\n      <td>-8.38</td>\n      <td>10.20</td>\n      <td>98.79</td>\n      <td>4.97</td>\n      <td>92.15</td>\n      <td>89.97</td>\n      <td>7.12</td>\n      <td>5.77</td>\n      <td>...</td>\n      <td>1.33</td>\n      <td>778.11</td>\n      <td>42.75</td>\n      <td>-0.81</td>\n      <td>7.38</td>\n      <td>5.94</td>\n      <td>6.26</td>\n      <td>-0.96</td>\n      <td>0.35</td>\n      <td>6.15</td>\n    </tr>\n    <tr>\n      <th>2025-09-30</th>\n      <td>-3.13</td>\n      <td>0.04</td>\n      <td>-8.32</td>\n      <td>10.78</td>\n      <td>98.52</td>\n      <td>5.14</td>\n      <td>92.32</td>\n      <td>89.99</td>\n      <td>7.80</td>\n      <td>5.92</td>\n      <td>...</td>\n      <td>2.00</td>\n      <td>730.91</td>\n      <td>53.75</td>\n      <td>-0.07</td>\n      <td>7.53</td>\n      <td>6.54</td>\n      <td>7.62</td>\n      <td>-0.97</td>\n      <td>0.63</td>\n      <td>6.50</td>\n    </tr>\n    <tr>\n      <th>2025-12-31</th>\n      <td>-2.20</td>\n      <td>0.05</td>\n      <td>-8.00</td>\n      <td>11.40</td>\n      <td>98.21</td>\n      <td>5.17</td>\n      <td>94.49</td>\n      <td>91.84</td>\n      <td>7.54</td>\n      <td>5.87</td>\n      <td>...</td>\n      <td>2.87</td>\n      <td>664.13</td>\n      <td>54.73</td>\n      <td>1.01</td>\n      <td>7.34</td>\n      <td>6.71</td>\n      <td>8.40</td>\n      <td>-0.69</td>\n      <td>1.03</td>\n      <td>6.52</td>\n    </tr>\n    <tr>\n      <th>2026-03-31</th>\n      <td>-1.66</td>\n      <td>0.09</td>\n      <td>-6.64</td>\n      <td>11.81</td>\n      <td>98.06</td>\n      <td>5.39</td>\n      <td>95.43</td>\n      <td>92.48</td>\n      <td>7.93</td>\n      <td>6.02</td>\n      <td>...</td>\n      <td>3.59</td>\n      <td>620.02</td>\n      <td>65.94</td>\n      <td>0.53</td>\n      <td>6.42</td>\n      <td>7.39</td>\n      <td>9.27</td>\n      <td>-0.98</td>\n      <td>1.21</td>\n      <td>6.70</td>\n    </tr>\n    <tr>\n      <th>2026-06-30</th>\n      <td>-0.85</td>\n      <td>0.16</td>\n      <td>-4.68</td>\n      <td>12.14</td>\n      <td>98.16</td>\n      <td>5.43</td>\n      <td>96.94</td>\n      <td>93.82</td>\n      <td>8.00</td>\n      <td>6.09</td>\n      <td>...</td>\n      <td>4.65</td>\n      <td>585.41</td>\n      <td>59.85</td>\n      <td>1.21</td>\n      <td>6.18</td>\n      <td>7.69</td>\n      <td>9.56</td>\n      <td>-0.85</td>\n      <td>1.36</td>\n      <td>6.78</td>\n    </tr>\n    <tr>\n      <th>2026-09-30</th>\n      <td>-0.23</td>\n      <td>0.24</td>\n      <td>-2.22</td>\n      <td>12.34</td>\n      <td>98.31</td>\n      <td>5.62</td>\n      <td>97.96</td>\n      <td>94.61</td>\n      <td>8.36</td>\n      <td>6.28</td>\n      <td>...</td>\n      <td>5.52</td>\n      <td>559.35</td>\n      <td>63.08</td>\n      <td>0.68</td>\n      <td>5.28</td>\n      <td>8.32</td>\n      <td>9.92</td>\n      <td>-1.11</td>\n      <td>1.40</td>\n      <td>6.92</td>\n    </tr>\n    <tr>\n      <th>2026-12-31</th>\n      <td>0.45</td>\n      <td>0.30</td>\n      <td>-0.12</td>\n      <td>12.53</td>\n      <td>98.50</td>\n      <td>5.70</td>\n      <td>99.25</td>\n      <td>95.74</td>\n      <td>8.50</td>\n      <td>6.39</td>\n      <td>...</td>\n      <td>6.37</td>\n      <td>536.12</td>\n      <td>59.12</td>\n      <td>0.95</td>\n      <td>4.96</td>\n      <td>8.69</td>\n      <td>10.06</td>\n      <td>-1.07</td>\n      <td>1.46</td>\n      <td>7.00</td>\n    </tr>\n    <tr>\n      <th>2027-03-31</th>\n      <td>0.92</td>\n      <td>0.38</td>\n      <td>2.09</td>\n      <td>12.67</td>\n      <td>98.72</td>\n      <td>5.79</td>\n      <td>99.84</td>\n      <td>96.26</td>\n      <td>8.85</td>\n      <td>6.53</td>\n      <td>...</td>\n      <td>7.22</td>\n      <td>523.14</td>\n      <td>55.55</td>\n      <td>0.95</td>\n      <td>4.57</td>\n      <td>9.10</td>\n      <td>10.22</td>\n      <td>-1.17</td>\n      <td>1.46</td>\n      <td>7.13</td>\n    </tr>\n    <tr>\n      <th>2027-06-30</th>\n      <td>1.35</td>\n      <td>0.41</td>\n      <td>3.21</td>\n      <td>12.82</td>\n      <td>98.85</td>\n      <td>5.86</td>\n      <td>100.79</td>\n      <td>97.09</td>\n      <td>8.97</td>\n      <td>6.62</td>\n      <td>...</td>\n      <td>7.71</td>\n      <td>505.16</td>\n      <td>53.97</td>\n      <td>1.45</td>\n      <td>4.67</td>\n      <td>9.35</td>\n      <td>10.41</td>\n      <td>-1.05</td>\n      <td>1.52</td>\n      <td>7.23</td>\n    </tr>\n    <tr>\n      <th>2027-09-30</th>\n      <td>1.62</td>\n      <td>0.43</td>\n      <td>4.15</td>\n      <td>12.95</td>\n      <td>98.99</td>\n      <td>5.90</td>\n      <td>101.24</td>\n      <td>97.51</td>\n      <td>9.21</td>\n      <td>6.72</td>\n      <td>...</td>\n      <td>8.15</td>\n      <td>494.70</td>\n      <td>51.70</td>\n      <td>2.01</td>\n      <td>4.93</td>\n      <td>9.57</td>\n      <td>10.62</td>\n      <td>-0.95</td>\n      <td>1.56</td>\n      <td>7.37</td>\n    </tr>\n    <tr>\n      <th>2027-12-31</th>\n      <td>1.77</td>\n      <td>0.41</td>\n      <td>4.08</td>\n      <td>13.08</td>\n      <td>99.09</td>\n      <td>5.92</td>\n      <td>101.79</td>\n      <td>98.06</td>\n      <td>9.33</td>\n      <td>6.78</td>\n      <td>...</td>\n      <td>8.27</td>\n      <td>484.11</td>\n      <td>49.79</td>\n      <td>3.23</td>\n      <td>5.86</td>\n      <td>9.62</td>\n      <td>10.86</td>\n      <td>-0.60</td>\n      <td>1.64</td>\n      <td>7.51</td>\n    </tr>\n  </tbody>\n</table>\n<p>12 rows × 25 columns</p>\n</div>"
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_inv_real = data_inv * data_sample.std() + data_sample.mean()\n",
    "data_inv_real"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:45:10.597559Z",
     "start_time": "2025-02-19T01:45:10.577300Z"
    }
   },
   "id": "1df8c423a7341757",
   "execution_count": 12
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 模块2： 风险传导模型"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "a6ed4c80d61d59f2"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            NPL  S2707411  S2700453  S0073300  M0009970  M0041340  M0012990  \\\nDate                                                                          \n2000-03-31  NaN       NaN       NaN     35.70     12.97     96.98       NaN   \n2000-06-30  NaN       NaN       NaN     36.70     13.83     97.20       NaN   \n2000-09-30  NaN       NaN       NaN     38.90     14.07     97.64       NaN   \n2000-12-31  NaN       NaN       NaN     26.90     14.20     95.74       NaN   \n2001-03-31  NaN       NaN       NaN     31.40     14.23     96.90       NaN   \n...         ...       ...       ...       ...       ...       ...       ...   \n2023-12-31 0.03     -0.73      0.07     -8.50     10.77     99.63      4.80   \n2024-03-31 0.03     -1.93      0.19    -19.40     10.03     98.97      5.30   \n2024-06-30 0.03     -4.23      0.22    -19.00      9.23     98.77      4.50   \n2024-09-30 0.03     -5.70      0.13    -17.10      8.43     98.30      4.20   \n2024-12-31 0.03     -6.00      0.34    -12.90      7.77     98.85      4.40   \n\n            M0012303  M0012304  M0024063  ...  M5650805  M5525763  M5525764  \\\nDate                                      ...                                 \n2000-03-31    110.03    109.97     24.23  ...       NaN       NaN       NaN   \n2000-06-30    110.97    110.70     13.40  ...       NaN       NaN       NaN   \n2000-09-30    111.87    111.80     28.27  ...       NaN       NaN       NaN   \n2000-12-31    112.70    112.43     12.31  ...       NaN       NaN       NaN   \n2001-03-31    113.10    112.83     29.33  ...       NaN       NaN       NaN   \n...              ...       ...       ...  ...       ...       ...       ...   \n2023-12-31     87.50     87.37     -0.51  ...      5.03      9.40     10.60   \n2024-03-31     89.13     88.23     -2.44  ...      5.23      9.07      9.67   \n2024-06-30     86.93     84.87     -3.20  ...      5.00      8.27      8.77   \n2024-09-30     85.83     84.37     -0.75  ...      5.20      8.10      8.07   \n2024-12-31     86.50     84.27     13.59  ...      5.03      7.87      7.43   \n\n            M0001385  M0001383  M0001428  M0001227  M0000612  M0000545  \\\nDate                                                                     \n2000-03-31     13.74     17.80     10.37      1.03      0.10     10.93   \n2000-06-30     14.29     22.57      9.83      2.07      0.10     11.70   \n2000-09-30     15.21     21.77      9.33      4.04      0.27     12.53   \n2000-12-31     14.45     17.10      9.30      3.30      0.93     10.80   \n2001-03-31     15.06     16.87     10.20      0.84      0.67     11.13   \n...              ...       ...       ...       ...       ...       ...   \n2023-12-31     10.00      1.50      8.37     -2.77     -0.33      6.00   \n2024-03-31      8.57      2.73      4.30     -2.67     -0.00      6.03   \n2024-06-30      6.80     -3.53      2.67     -1.57      0.27      5.87   \n2024-09-30      6.47     -7.10      2.67     -1.80      0.50      5.00   \n2024-12-31      7.30     -3.73      3.83     -2.57      0.20      5.63   \n\n            NPL_logit  \nDate                   \n2000-03-31        NaN  \n2000-06-30        NaN  \n2000-09-30        NaN  \n2000-12-31        NaN  \n2001-03-31        NaN  \n...               ...  \n2023-12-31      -3.39  \n2024-03-31      -3.48  \n2024-06-30      -3.43  \n2024-09-30      -3.53  \n2024-12-31      -3.59  \n\n[100 rows x 22 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>NPL</th>\n      <th>S2707411</th>\n      <th>S2700453</th>\n      <th>S0073300</th>\n      <th>M0009970</th>\n      <th>M0041340</th>\n      <th>M0012990</th>\n      <th>M0012303</th>\n      <th>M0012304</th>\n      <th>M0024063</th>\n      <th>...</th>\n      <th>M5650805</th>\n      <th>M5525763</th>\n      <th>M5525764</th>\n      <th>M0001385</th>\n      <th>M0001383</th>\n      <th>M0001428</th>\n      <th>M0001227</th>\n      <th>M0000612</th>\n      <th>M0000545</th>\n      <th>NPL_logit</th>\n    </tr>\n    <tr>\n      <th>Date</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2000-03-31</th>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>35.70</td>\n      <td>12.97</td>\n      <td>96.98</td>\n      <td>NaN</td>\n      <td>110.03</td>\n      <td>109.97</td>\n      <td>24.23</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>13.74</td>\n      <td>17.80</td>\n      <td>10.37</td>\n      <td>1.03</td>\n      <td>0.10</td>\n      <td>10.93</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2000-06-30</th>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>36.70</td>\n      <td>13.83</td>\n      <td>97.20</td>\n      <td>NaN</td>\n      <td>110.97</td>\n      <td>110.70</td>\n      <td>13.40</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>14.29</td>\n      <td>22.57</td>\n      <td>9.83</td>\n      <td>2.07</td>\n      <td>0.10</td>\n      <td>11.70</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2000-09-30</th>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>38.90</td>\n      <td>14.07</td>\n      <td>97.64</td>\n      <td>NaN</td>\n      <td>111.87</td>\n      <td>111.80</td>\n      <td>28.27</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>15.21</td>\n      <td>21.77</td>\n      <td>9.33</td>\n      <td>4.04</td>\n      <td>0.27</td>\n      <td>12.53</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2000-12-31</th>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>26.90</td>\n      <td>14.20</td>\n      <td>95.74</td>\n      <td>NaN</td>\n      <td>112.70</td>\n      <td>112.43</td>\n      <td>12.31</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>14.45</td>\n      <td>17.10</td>\n      <td>9.30</td>\n      <td>3.30</td>\n      <td>0.93</td>\n      <td>10.80</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2001-03-31</th>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>31.40</td>\n      <td>14.23</td>\n      <td>96.90</td>\n      <td>NaN</td>\n      <td>113.10</td>\n      <td>112.83</td>\n      <td>29.33</td>\n      <td>...</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>15.06</td>\n      <td>16.87</td>\n      <td>10.20</td>\n      <td>0.84</td>\n      <td>0.67</td>\n      <td>11.13</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>2023-12-31</th>\n      <td>0.03</td>\n      <td>-0.73</td>\n      <td>0.07</td>\n      <td>-8.50</td>\n      <td>10.77</td>\n      <td>99.63</td>\n      <td>4.80</td>\n      <td>87.50</td>\n      <td>87.37</td>\n      <td>-0.51</td>\n      <td>...</td>\n      <td>5.03</td>\n      <td>9.40</td>\n      <td>10.60</td>\n      <td>10.00</td>\n      <td>1.50</td>\n      <td>8.37</td>\n      <td>-2.77</td>\n      <td>-0.33</td>\n      <td>6.00</td>\n      <td>-3.39</td>\n    </tr>\n    <tr>\n      <th>2024-03-31</th>\n      <td>0.03</td>\n      <td>-1.93</td>\n      <td>0.19</td>\n      <td>-19.40</td>\n      <td>10.03</td>\n      <td>98.97</td>\n      <td>5.30</td>\n      <td>89.13</td>\n      <td>88.23</td>\n      <td>-2.44</td>\n      <td>...</td>\n      <td>5.23</td>\n      <td>9.07</td>\n      <td>9.67</td>\n      <td>8.57</td>\n      <td>2.73</td>\n      <td>4.30</td>\n      <td>-2.67</td>\n      <td>-0.00</td>\n      <td>6.03</td>\n      <td>-3.48</td>\n    </tr>\n    <tr>\n      <th>2024-06-30</th>\n      <td>0.03</td>\n      <td>-4.23</td>\n      <td>0.22</td>\n      <td>-19.00</td>\n      <td>9.23</td>\n      <td>98.77</td>\n      <td>4.50</td>\n      <td>86.93</td>\n      <td>84.87</td>\n      <td>-3.20</td>\n      <td>...</td>\n      <td>5.00</td>\n      <td>8.27</td>\n      <td>8.77</td>\n      <td>6.80</td>\n      <td>-3.53</td>\n      <td>2.67</td>\n      <td>-1.57</td>\n      <td>0.27</td>\n      <td>5.87</td>\n      <td>-3.43</td>\n    </tr>\n    <tr>\n      <th>2024-09-30</th>\n      <td>0.03</td>\n      <td>-5.70</td>\n      <td>0.13</td>\n      <td>-17.10</td>\n      <td>8.43</td>\n      <td>98.30</td>\n      <td>4.20</td>\n      <td>85.83</td>\n      <td>84.37</td>\n      <td>-0.75</td>\n      <td>...</td>\n      <td>5.20</td>\n      <td>8.10</td>\n      <td>8.07</td>\n      <td>6.47</td>\n      <td>-7.10</td>\n      <td>2.67</td>\n      <td>-1.80</td>\n      <td>0.50</td>\n      <td>5.00</td>\n      <td>-3.53</td>\n    </tr>\n    <tr>\n      <th>2024-12-31</th>\n      <td>0.03</td>\n      <td>-6.00</td>\n      <td>0.34</td>\n      <td>-12.90</td>\n      <td>7.77</td>\n      <td>98.85</td>\n      <td>4.40</td>\n      <td>86.50</td>\n      <td>84.27</td>\n      <td>13.59</td>\n      <td>...</td>\n      <td>5.03</td>\n      <td>7.87</td>\n      <td>7.43</td>\n      <td>7.30</td>\n      <td>-3.73</td>\n      <td>3.83</td>\n      <td>-2.57</td>\n      <td>0.20</td>\n      <td>5.63</td>\n      <td>-3.59</td>\n    </tr>\n  </tbody>\n</table>\n<p>100 rows × 22 columns</p>\n</div>"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 季末处理的指标清单\n",
    "x_qe_list: list = ['S0073300', 'M0012990', 'M0000541', 'M0000273']\n",
    "\n",
    "file_path = r'E:\\Psbc\\03.组合风险\\06.压力测试\\2024Q4\\信用风险\\\\中邮消费金融2024年信用风险压力测试工作底稿.xlsx'\n",
    "data_raw = pd.read_excel(file_path, sheet_name='原始数据', index_col=0)\n",
    "data_raw.index = pd.to_datetime(pd.to_datetime(data_raw.index).astype(str).map(lambda x: intnx(x, 'm', 0, 'e')))\n",
    "data_model_sample = data_raw.resample('QE').mean()\n",
    "data_model_sample[x_qe_list] = data_raw[x_qe_list].resample('QE').last()\n",
    "data_model_sample['NPL_logit'] = np.log(data_model_sample['NPL'] / (1 - data_model_sample['NPL']))\n",
    "\n",
    "xs_drop = ['M0000610', 'M0000611', 'M0000609', 'M0000607', 'M0000273']  #较难解释，不优先\n",
    "data_model_sample = data_model_sample.drop(xs_drop, axis=1)\n",
    "data_model_sample"
   ],
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:45:11.534776Z",
     "start_time": "2025-02-19T01:45:10.605549Z"
    }
   },
   "id": "initial_id",
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "            S2707411  S2700453  S0073300  M0009970  M0041340  M0012990  \\\nDate                                                                     \n2017-03-31     10.53      0.67     19.50     12.67    103.15      6.30   \n2017-06-30      9.73      0.70     16.10     12.90    103.63      6.50   \n2017-09-30      8.00      0.54     10.30     13.17    103.27      6.59   \n2017-12-31      5.67      0.39      7.70     13.00    103.16      6.46   \n2018-03-31      5.57      0.39      3.60     12.93    103.73      5.70   \n2018-06-30      5.50      0.48      3.30     12.67    102.86      5.80   \n2018-09-30      7.83      0.46      2.90     13.20    101.55      5.70   \n2018-12-31     10.20      0.33      1.30     13.23    100.10      5.60   \n2019-03-31     11.07      0.19     -0.90     13.50     99.68      5.90   \n2019-06-30     11.17      0.30     -1.80     13.30     98.87      5.70   \n2019-09-30      9.27      0.35     -0.10     12.50     98.29      5.40   \n2019-12-31      7.37      0.26     -0.10     12.37     94.19      5.00   \n2020-03-31      5.93      0.06    -26.30     12.30     87.08     -3.90   \n2020-06-30      5.00      0.36     -8.40     13.17     92.05     -2.00   \n2020-09-30      4.67      0.39     -1.80     13.00     98.71     -0.30   \n2020-12-31      3.97      0.32      2.60     12.83    106.50      1.20   \n2021-03-31      4.07      0.26     63.80     12.73    115.65     12.30   \n2021-06-30      4.40      0.31     27.70     12.27    109.68     10.70   \n2021-09-30      3.70      0.23     11.30     12.10    100.67      8.70   \n2021-12-31      2.40      0.01      1.90     11.73     97.96      7.10   \n2022-03-31      1.20      0.02    -13.80     11.43     96.86      4.20   \n2022-06-30     -0.73      0.03    -22.20     11.03     94.33      1.90   \n2022-09-30     -2.03     -0.01    -22.20     11.03     96.23      2.30   \n2022-12-31     -2.33     -0.05    -24.30     11.07     94.83      1.90   \n2023-03-31     -1.87      0.00     -1.80     11.57     96.56      2.70   \n2023-06-30     -0.53      0.00     -5.30     11.50     98.17      4.70   \n2023-09-30     -0.60      0.01     -7.50     11.03     98.73      4.70   \n2023-12-31     -0.73      0.07     -8.50     10.77     99.63      4.80   \n2024-03-31     -1.93      0.19    -19.40     10.03     98.97      5.30   \n2024-06-30     -4.23      0.22    -19.00      9.23     98.77      4.50   \n2024-09-30     -5.70      0.13    -17.10      8.43     98.30      4.20   \n2024-12-31     -6.00      0.34    -12.90      7.77     98.85      4.40   \n\n            M0012303  M0012304  M0024063  M0000541  ...  M5650805_lag4  \\\nDate                                                ...                  \n2017-03-31    110.93    105.97     13.31      7.00  ...           5.01   \n2017-06-30    112.90    108.40      6.80      7.00  ...           5.01   \n2017-09-30    115.97    111.43      9.17      7.00  ...           5.01   \n2017-12-31    122.60    117.43     -0.09      6.95  ...           5.01   \n2018-03-31    122.87    117.77     13.29      6.90  ...           5.01   \n2018-06-30    121.33    116.43      7.75      6.90  ...           5.01   \n2018-09-30    118.93    114.27      4.02      6.80  ...           5.01   \n2018-12-31    121.40    116.63     -2.21      6.75  ...           5.01   \n2019-03-31    124.60    119.60      3.99      6.30  ...           5.01   \n2019-06-30    124.87    120.00      0.72      6.10  ...           4.83   \n2019-09-30    123.63    118.53      3.37      6.00  ...           5.00   \n2019-12-31    125.17    118.83      5.46      5.95  ...           4.87   \n2020-03-31    122.50    117.73    -26.11     -6.90  ...           5.20   \n2020-06-30    114.93    110.83     -7.26     -1.70  ...           5.03   \n2020-09-30    118.03    112.57      4.72      0.60  ...           5.23   \n2020-12-31    122.60    117.83      5.89      2.24  ...           5.13   \n2021-03-31    124.00    118.13     42.39     18.70  ...           5.80   \n2021-06-30    122.03    116.27     19.92     13.00  ...           5.87   \n2021-09-30    118.83    115.17      3.89     10.10  ...           5.57   \n2021-12-31    119.83    115.43     -9.06      8.45  ...           5.23   \n2022-03-31    118.40    114.23      3.42      4.80  ...           5.40   \n2022-06-30     87.47     86.73    -28.14      2.50  ...           5.03   \n2022-09-30     87.37     86.57      3.31      3.00  ...           5.03   \n2022-12-31     86.87     86.83     33.80      2.95  ...           5.00   \n2023-03-31     93.60     91.57      5.46      4.50  ...           5.53   \n2023-06-30     87.23     86.33     36.09      5.50  ...           5.83   \n2023-09-30     86.70     86.40     -1.33      5.20  ...           5.40   \n2023-12-31     87.50     87.37     -0.51      5.25  ...           5.57   \n2024-03-31     89.13     88.23     -2.44      5.30  ...           5.47   \n2024-06-30     86.93     84.87     -3.20      5.00  ...           5.20   \n2024-09-30     85.83     84.37     -0.75      4.80  ...           5.17   \n2024-12-31     86.50     84.27     13.59      5.00  ...           5.03   \n\n            M5525763_lag4  M5525764_lag4  M0001385_lag4  M0001383_lag4  \\\nDate                                                                     \n2017-03-31          13.07          14.57          13.57          19.37   \n2017-06-30          12.70          13.97          12.13          23.73   \n2017-09-30          12.33          13.57          11.03          25.13   \n2017-12-31          12.93          13.43          11.43          22.67   \n2018-03-31          16.17          12.78          10.40          18.23   \n2018-06-30          15.31          13.12           9.33          16.83   \n2018-09-30          15.18          13.61           8.83          14.43   \n2018-12-31          14.51          13.45           8.70          12.50   \n2019-03-31          13.17          13.07           8.53          10.20   \n2019-06-30          12.20          12.71           8.20           6.60   \n2019-09-30          11.40          12.95           8.33           4.33   \n2019-12-31          10.45          13.02           8.03           1.90   \n2020-03-31          10.89          13.57           8.33           2.33   \n2020-06-30          11.01          13.40           8.50           3.57   \n2020-09-30          10.73          12.69           8.23           3.30   \n2020-12-31          10.65          12.53           8.43           3.73   \n2021-03-31          10.97          12.33           9.10           3.27   \n2021-06-30          12.43          13.23          11.10           6.27   \n2021-09-30          13.23          13.27          10.67           7.67   \n2021-12-31          13.53          13.27          10.43           9.23   \n2022-03-31          12.87          13.20           9.63           9.73   \n2022-06-30          11.23          12.60           8.33           5.93   \n2022-09-30          10.33          12.20           8.27           4.27   \n2022-12-31          10.13          11.80           8.73           3.10   \n2023-03-31          10.40          11.37           9.57           2.50   \n2023-06-30          10.50          10.90          11.00           5.17   \n2023-09-30          10.60          10.93          12.10           6.40   \n2023-12-31           9.97          10.87          12.00           4.70   \n2024-03-31           9.77          11.43          12.73           5.87   \n2024-06-30           9.50          11.40          11.77           4.37   \n2024-09-30           8.97          10.87          10.53           2.20   \n2024-12-31           9.40          10.60          10.00           1.50   \n\n            M0001428_lag4  M0001227_lag4  M0000612_lag4  M0000545_lag4  \\\nDate                                                                     \n2017-03-31          10.35          -4.83           2.13           5.86   \n2017-06-30          10.23          -2.93           2.08           6.07   \n2017-09-30          10.50          -0.80           1.68           6.13   \n2017-12-31          10.57           3.33           2.14           6.10   \n2018-03-31          10.20           7.43           1.42           6.95   \n2018-06-30          10.80           5.80           1.40           6.87   \n2018-09-30          10.27           6.23           1.60           6.33   \n2018-12-31           9.87           5.87           1.80           6.17   \n2019-03-31           9.90           3.70           2.17           6.44   \n2019-06-30           8.97           4.07           1.83           6.60   \n2019-09-30           9.00           4.10           2.30           5.97   \n2019-12-31           8.29           2.30           2.20           5.67   \n2020-03-31           8.45           0.20           1.83           6.22   \n2020-06-30           8.53           0.50           2.63           5.57   \n2020-09-30           7.63          -0.77           2.87           5.00   \n2020-12-31           7.73          -1.17           4.27           5.93   \n2021-03-31         -18.15          -0.60           4.97         -10.43   \n2021-06-30          -4.03          -3.27           2.73           4.37   \n2021-09-30           0.90          -2.17           2.27           5.77   \n2021-12-31           4.63          -1.33           0.07           7.07   \n2022-03-31          34.00           2.13          -0.03          30.61   \n2022-06-30          14.07           8.20           1.10           8.97   \n2022-09-30           5.13           9.73           0.83           4.93   \n2022-12-31           3.50          12.23           1.77           3.87   \n2023-03-31           1.59           8.73           1.10           7.22   \n2023-06-30          -4.90           6.83           2.23           0.57   \n2023-09-30           3.53           2.47           2.67           4.77   \n2023-12-31          -2.73          -1.10           1.83           2.83   \n2024-03-31           7.05          -1.57           1.27           4.29   \n2024-06-30          11.40          -4.53           0.10           4.50   \n2024-09-30           4.20          -3.30          -0.07           4.23   \n2024-12-31           8.37          -2.77          -0.33           6.00   \n\n            NPL_logit_lag4  \nDate                        \n2017-03-31           -5.63  \n2017-06-30           -5.63  \n2017-09-30           -5.63  \n2017-12-31           -5.63  \n2018-03-31           -5.63  \n2018-06-30           -5.32  \n2018-09-30           -5.14  \n2018-12-31           -4.64  \n2019-03-31           -4.19  \n2019-06-30           -3.74  \n2019-09-30           -3.72  \n2019-12-31           -3.64  \n2020-03-31           -3.37  \n2020-06-30           -3.35  \n2020-09-30           -3.36  \n2020-12-31           -3.37  \n2021-03-31           -3.40  \n2021-06-30           -3.20  \n2021-09-30           -3.30  \n2021-12-31           -3.47  \n2022-03-31           -3.56  \n2022-06-30           -3.68  \n2022-09-30           -3.86  \n2022-12-31           -3.82  \n2023-03-31           -3.47  \n2023-06-30           -3.26  \n2023-09-30           -3.27  \n2023-12-31           -3.41  \n2024-03-31           -3.44  \n2024-06-30           -3.46  \n2024-09-30           -3.48  \n2024-12-31           -3.39  \n\n[32 rows x 109 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>S2707411</th>\n      <th>S2700453</th>\n      <th>S0073300</th>\n      <th>M0009970</th>\n      <th>M0041340</th>\n      <th>M0012990</th>\n      <th>M0012303</th>\n      <th>M0012304</th>\n      <th>M0024063</th>\n      <th>M0000541</th>\n      <th>...</th>\n      <th>M5650805_lag4</th>\n      <th>M5525763_lag4</th>\n      <th>M5525764_lag4</th>\n      <th>M0001385_lag4</th>\n      <th>M0001383_lag4</th>\n      <th>M0001428_lag4</th>\n      <th>M0001227_lag4</th>\n      <th>M0000612_lag4</th>\n      <th>M0000545_lag4</th>\n      <th>NPL_logit_lag4</th>\n    </tr>\n    <tr>\n      <th>Date</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2017-03-31</th>\n      <td>10.53</td>\n      <td>0.67</td>\n      <td>19.50</td>\n      <td>12.67</td>\n      <td>103.15</td>\n      <td>6.30</td>\n      <td>110.93</td>\n      <td>105.97</td>\n      <td>13.31</td>\n      <td>7.00</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>13.07</td>\n      <td>14.57</td>\n      <td>13.57</td>\n      <td>19.37</td>\n      <td>10.35</td>\n      <td>-4.83</td>\n      <td>2.13</td>\n      <td>5.86</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2017-06-30</th>\n      <td>9.73</td>\n      <td>0.70</td>\n      <td>16.10</td>\n      <td>12.90</td>\n      <td>103.63</td>\n      <td>6.50</td>\n      <td>112.90</td>\n      <td>108.40</td>\n      <td>6.80</td>\n      <td>7.00</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>12.70</td>\n      <td>13.97</td>\n      <td>12.13</td>\n      <td>23.73</td>\n      <td>10.23</td>\n      <td>-2.93</td>\n      <td>2.08</td>\n      <td>6.07</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2017-09-30</th>\n      <td>8.00</td>\n      <td>0.54</td>\n      <td>10.30</td>\n      <td>13.17</td>\n      <td>103.27</td>\n      <td>6.59</td>\n      <td>115.97</td>\n      <td>111.43</td>\n      <td>9.17</td>\n      <td>7.00</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>12.33</td>\n      <td>13.57</td>\n      <td>11.03</td>\n      <td>25.13</td>\n      <td>10.50</td>\n      <td>-0.80</td>\n      <td>1.68</td>\n      <td>6.13</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2017-12-31</th>\n      <td>5.67</td>\n      <td>0.39</td>\n      <td>7.70</td>\n      <td>13.00</td>\n      <td>103.16</td>\n      <td>6.46</td>\n      <td>122.60</td>\n      <td>117.43</td>\n      <td>-0.09</td>\n      <td>6.95</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>12.93</td>\n      <td>13.43</td>\n      <td>11.43</td>\n      <td>22.67</td>\n      <td>10.57</td>\n      <td>3.33</td>\n      <td>2.14</td>\n      <td>6.10</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2018-03-31</th>\n      <td>5.57</td>\n      <td>0.39</td>\n      <td>3.60</td>\n      <td>12.93</td>\n      <td>103.73</td>\n      <td>5.70</td>\n      <td>122.87</td>\n      <td>117.77</td>\n      <td>13.29</td>\n      <td>6.90</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>16.17</td>\n      <td>12.78</td>\n      <td>10.40</td>\n      <td>18.23</td>\n      <td>10.20</td>\n      <td>7.43</td>\n      <td>1.42</td>\n      <td>6.95</td>\n      <td>-5.63</td>\n    </tr>\n    <tr>\n      <th>2018-06-30</th>\n      <td>5.50</td>\n      <td>0.48</td>\n      <td>3.30</td>\n      <td>12.67</td>\n      <td>102.86</td>\n      <td>5.80</td>\n      <td>121.33</td>\n      <td>116.43</td>\n      <td>7.75</td>\n      <td>6.90</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>15.31</td>\n      <td>13.12</td>\n      <td>9.33</td>\n      <td>16.83</td>\n      <td>10.80</td>\n      <td>5.80</td>\n      <td>1.40</td>\n      <td>6.87</td>\n      <td>-5.32</td>\n    </tr>\n    <tr>\n      <th>2018-09-30</th>\n      <td>7.83</td>\n      <td>0.46</td>\n      <td>2.90</td>\n      <td>13.20</td>\n      <td>101.55</td>\n      <td>5.70</td>\n      <td>118.93</td>\n      <td>114.27</td>\n      <td>4.02</td>\n      <td>6.80</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>15.18</td>\n      <td>13.61</td>\n      <td>8.83</td>\n      <td>14.43</td>\n      <td>10.27</td>\n      <td>6.23</td>\n      <td>1.60</td>\n      <td>6.33</td>\n      <td>-5.14</td>\n    </tr>\n    <tr>\n      <th>2018-12-31</th>\n      <td>10.20</td>\n      <td>0.33</td>\n      <td>1.30</td>\n      <td>13.23</td>\n      <td>100.10</td>\n      <td>5.60</td>\n      <td>121.40</td>\n      <td>116.63</td>\n      <td>-2.21</td>\n      <td>6.75</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>14.51</td>\n      <td>13.45</td>\n      <td>8.70</td>\n      <td>12.50</td>\n      <td>9.87</td>\n      <td>5.87</td>\n      <td>1.80</td>\n      <td>6.17</td>\n      <td>-4.64</td>\n    </tr>\n    <tr>\n      <th>2019-03-31</th>\n      <td>11.07</td>\n      <td>0.19</td>\n      <td>-0.90</td>\n      <td>13.50</td>\n      <td>99.68</td>\n      <td>5.90</td>\n      <td>124.60</td>\n      <td>119.60</td>\n      <td>3.99</td>\n      <td>6.30</td>\n      <td>...</td>\n      <td>5.01</td>\n      <td>13.17</td>\n      <td>13.07</td>\n      <td>8.53</td>\n      <td>10.20</td>\n      <td>9.90</td>\n      <td>3.70</td>\n      <td>2.17</td>\n      <td>6.44</td>\n      <td>-4.19</td>\n    </tr>\n    <tr>\n      <th>2019-06-30</th>\n      <td>11.17</td>\n      <td>0.30</td>\n      <td>-1.80</td>\n      <td>13.30</td>\n      <td>98.87</td>\n      <td>5.70</td>\n      <td>124.87</td>\n      <td>120.00</td>\n      <td>0.72</td>\n      <td>6.10</td>\n      <td>...</td>\n      <td>4.83</td>\n      <td>12.20</td>\n      <td>12.71</td>\n      <td>8.20</td>\n      <td>6.60</td>\n      <td>8.97</td>\n      <td>4.07</td>\n      <td>1.83</td>\n      <td>6.60</td>\n      <td>-3.74</td>\n    </tr>\n    <tr>\n      <th>2019-09-30</th>\n      <td>9.27</td>\n      <td>0.35</td>\n      <td>-0.10</td>\n      <td>12.50</td>\n      <td>98.29</td>\n      <td>5.40</td>\n      <td>123.63</td>\n      <td>118.53</td>\n      <td>3.37</td>\n      <td>6.00</td>\n      <td>...</td>\n      <td>5.00</td>\n      <td>11.40</td>\n      <td>12.95</td>\n      <td>8.33</td>\n      <td>4.33</td>\n      <td>9.00</td>\n      <td>4.10</td>\n      <td>2.30</td>\n      <td>5.97</td>\n      <td>-3.72</td>\n    </tr>\n    <tr>\n      <th>2019-12-31</th>\n      <td>7.37</td>\n      <td>0.26</td>\n      <td>-0.10</td>\n      <td>12.37</td>\n      <td>94.19</td>\n      <td>5.00</td>\n      <td>125.17</td>\n      <td>118.83</td>\n      <td>5.46</td>\n      <td>5.95</td>\n      <td>...</td>\n      <td>4.87</td>\n      <td>10.45</td>\n      <td>13.02</td>\n      <td>8.03</td>\n      <td>1.90</td>\n      <td>8.29</td>\n      <td>2.30</td>\n      <td>2.20</td>\n      <td>5.67</td>\n      <td>-3.64</td>\n    </tr>\n    <tr>\n      <th>2020-03-31</th>\n      <td>5.93</td>\n      <td>0.06</td>\n      <td>-26.30</td>\n      <td>12.30</td>\n      <td>87.08</td>\n      <td>-3.90</td>\n      <td>122.50</td>\n      <td>117.73</td>\n      <td>-26.11</td>\n      <td>-6.90</td>\n      <td>...</td>\n      <td>5.20</td>\n      <td>10.89</td>\n      <td>13.57</td>\n      <td>8.33</td>\n      <td>2.33</td>\n      <td>8.45</td>\n      <td>0.20</td>\n      <td>1.83</td>\n      <td>6.22</td>\n      <td>-3.37</td>\n    </tr>\n    <tr>\n      <th>2020-06-30</th>\n      <td>5.00</td>\n      <td>0.36</td>\n      <td>-8.40</td>\n      <td>13.17</td>\n      <td>92.05</td>\n      <td>-2.00</td>\n      <td>114.93</td>\n      <td>110.83</td>\n      <td>-7.26</td>\n      <td>-1.70</td>\n      <td>...</td>\n      <td>5.03</td>\n      <td>11.01</td>\n      <td>13.40</td>\n      <td>8.50</td>\n      <td>3.57</td>\n      <td>8.53</td>\n      <td>0.50</td>\n      <td>2.63</td>\n      <td>5.57</td>\n      <td>-3.35</td>\n    </tr>\n    <tr>\n      <th>2020-09-30</th>\n      <td>4.67</td>\n      <td>0.39</td>\n      <td>-1.80</td>\n      <td>13.00</td>\n      <td>98.71</td>\n      <td>-0.30</td>\n      <td>118.03</td>\n      <td>112.57</td>\n      <td>4.72</td>\n      <td>0.60</td>\n      <td>...</td>\n      <td>5.23</td>\n      <td>10.73</td>\n      <td>12.69</td>\n      <td>8.23</td>\n      <td>3.30</td>\n      <td>7.63</td>\n      <td>-0.77</td>\n      <td>2.87</td>\n      <td>5.00</td>\n      <td>-3.36</td>\n    </tr>\n    <tr>\n      <th>2020-12-31</th>\n      <td>3.97</td>\n      <td>0.32</td>\n      <td>2.60</td>\n      <td>12.83</td>\n      <td>106.50</td>\n      <td>1.20</td>\n      <td>122.60</td>\n      <td>117.83</td>\n      <td>5.89</td>\n      <td>2.24</td>\n      <td>...</td>\n      <td>5.13</td>\n      <td>10.65</td>\n      <td>12.53</td>\n      <td>8.43</td>\n      <td>3.73</td>\n      <td>7.73</td>\n      <td>-1.17</td>\n      <td>4.27</td>\n      <td>5.93</td>\n      <td>-3.37</td>\n    </tr>\n    <tr>\n      <th>2021-03-31</th>\n      <td>4.07</td>\n      <td>0.26</td>\n      <td>63.80</td>\n      <td>12.73</td>\n      <td>115.65</td>\n      <td>12.30</td>\n      <td>124.00</td>\n      <td>118.13</td>\n      <td>42.39</td>\n      <td>18.70</td>\n      <td>...</td>\n      <td>5.80</td>\n      <td>10.97</td>\n      <td>12.33</td>\n      <td>9.10</td>\n      <td>3.27</td>\n      <td>-18.15</td>\n      <td>-0.60</td>\n      <td>4.97</td>\n      <td>-10.43</td>\n      <td>-3.40</td>\n    </tr>\n    <tr>\n      <th>2021-06-30</th>\n      <td>4.40</td>\n      <td>0.31</td>\n      <td>27.70</td>\n      <td>12.27</td>\n      <td>109.68</td>\n      <td>10.70</td>\n      <td>122.03</td>\n      <td>116.27</td>\n      <td>19.92</td>\n      <td>13.00</td>\n      <td>...</td>\n      <td>5.87</td>\n      <td>12.43</td>\n      <td>13.23</td>\n      <td>11.10</td>\n      <td>6.27</td>\n      <td>-4.03</td>\n      <td>-3.27</td>\n      <td>2.73</td>\n      <td>4.37</td>\n      <td>-3.20</td>\n    </tr>\n    <tr>\n      <th>2021-09-30</th>\n      <td>3.70</td>\n      <td>0.23</td>\n      <td>11.30</td>\n      <td>12.10</td>\n      <td>100.67</td>\n      <td>8.70</td>\n      <td>118.83</td>\n      <td>115.17</td>\n      <td>3.89</td>\n      <td>10.10</td>\n      <td>...</td>\n      <td>5.57</td>\n      <td>13.23</td>\n      <td>13.27</td>\n      <td>10.67</td>\n      <td>7.67</td>\n      <td>0.90</td>\n      <td>-2.17</td>\n      <td>2.27</td>\n      <td>5.77</td>\n      <td>-3.30</td>\n    </tr>\n    <tr>\n      <th>2021-12-31</th>\n      <td>2.40</td>\n      <td>0.01</td>\n      <td>1.90</td>\n      <td>11.73</td>\n      <td>97.96</td>\n      <td>7.10</td>\n      <td>119.83</td>\n      <td>115.43</td>\n      <td>-9.06</td>\n      <td>8.45</td>\n      <td>...</td>\n      <td>5.23</td>\n      <td>13.53</td>\n      <td>13.27</td>\n      <td>10.43</td>\n      <td>9.23</td>\n      <td>4.63</td>\n      <td>-1.33</td>\n      <td>0.07</td>\n      <td>7.07</td>\n      <td>-3.47</td>\n    </tr>\n    <tr>\n      <th>2022-03-31</th>\n      <td>1.20</td>\n      <td>0.02</td>\n      <td>-13.80</td>\n      <td>11.43</td>\n      <td>96.86</td>\n      <td>4.20</td>\n      <td>118.40</td>\n      <td>114.23</td>\n      <td>3.42</td>\n      <td>4.80</td>\n      <td>...</td>\n      <td>5.40</td>\n      <td>12.87</td>\n      <td>13.20</td>\n      <td>9.63</td>\n      <td>9.73</td>\n      <td>34.00</td>\n      <td>2.13</td>\n      <td>-0.03</td>\n      <td>30.61</td>\n      <td>-3.56</td>\n    </tr>\n    <tr>\n      <th>2022-06-30</th>\n      <td>-0.73</td>\n      <td>0.03</td>\n      <td>-22.20</td>\n      <td>11.03</td>\n      <td>94.33</td>\n      <td>1.90</td>\n      <td>87.47</td>\n      <td>86.73</td>\n      <td>-28.14</td>\n      <td>2.50</td>\n      <td>...</td>\n      <td>5.03</td>\n      <td>11.23</td>\n      <td>12.60</td>\n      <td>8.33</td>\n      <td>5.93</td>\n      <td>14.07</td>\n      <td>8.20</td>\n      <td>1.10</td>\n      <td>8.97</td>\n      <td>-3.68</td>\n    </tr>\n    <tr>\n      <th>2022-09-30</th>\n      <td>-2.03</td>\n      <td>-0.01</td>\n      <td>-22.20</td>\n      <td>11.03</td>\n      <td>96.23</td>\n      <td>2.30</td>\n      <td>87.37</td>\n      <td>86.57</td>\n      <td>3.31</td>\n      <td>3.00</td>\n      <td>...</td>\n      <td>5.03</td>\n      <td>10.33</td>\n      <td>12.20</td>\n      <td>8.27</td>\n      <td>4.27</td>\n      <td>5.13</td>\n      <td>9.73</td>\n      <td>0.83</td>\n      <td>4.93</td>\n      <td>-3.86</td>\n    </tr>\n    <tr>\n      <th>2022-12-31</th>\n      <td>-2.33</td>\n      <td>-0.05</td>\n      <td>-24.30</td>\n      <td>11.07</td>\n      <td>94.83</td>\n      <td>1.90</td>\n      <td>86.87</td>\n      <td>86.83</td>\n      <td>33.80</td>\n      <td>2.95</td>\n      <td>...</td>\n      <td>5.00</td>\n      <td>10.13</td>\n      <td>11.80</td>\n      <td>8.73</td>\n      <td>3.10</td>\n      <td>3.50</td>\n      <td>12.23</td>\n      <td>1.77</td>\n      <td>3.87</td>\n      <td>-3.82</td>\n    </tr>\n    <tr>\n      <th>2023-03-31</th>\n      <td>-1.87</td>\n      <td>0.00</td>\n      <td>-1.80</td>\n      <td>11.57</td>\n      <td>96.56</td>\n      <td>2.70</td>\n      <td>93.60</td>\n      <td>91.57</td>\n      <td>5.46</td>\n      <td>4.50</td>\n      <td>...</td>\n      <td>5.53</td>\n      <td>10.40</td>\n      <td>11.37</td>\n      <td>9.57</td>\n      <td>2.50</td>\n      <td>1.59</td>\n      <td>8.73</td>\n      <td>1.10</td>\n      <td>7.22</td>\n      <td>-3.47</td>\n    </tr>\n    <tr>\n      <th>2023-06-30</th>\n      <td>-0.53</td>\n      <td>0.00</td>\n      <td>-5.30</td>\n      <td>11.50</td>\n      <td>98.17</td>\n      <td>4.70</td>\n      <td>87.23</td>\n      <td>86.33</td>\n      <td>36.09</td>\n      <td>5.50</td>\n      <td>...</td>\n      <td>5.83</td>\n      <td>10.50</td>\n      <td>10.90</td>\n      <td>11.00</td>\n      <td>5.17</td>\n      <td>-4.90</td>\n      <td>6.83</td>\n      <td>2.23</td>\n      <td>0.57</td>\n      <td>-3.26</td>\n    </tr>\n    <tr>\n      <th>2023-09-30</th>\n      <td>-0.60</td>\n      <td>0.01</td>\n      <td>-7.50</td>\n      <td>11.03</td>\n      <td>98.73</td>\n      <td>4.70</td>\n      <td>86.70</td>\n      <td>86.40</td>\n      <td>-1.33</td>\n      <td>5.20</td>\n      <td>...</td>\n      <td>5.40</td>\n      <td>10.60</td>\n      <td>10.93</td>\n      <td>12.10</td>\n      <td>6.40</td>\n      <td>3.53</td>\n      <td>2.47</td>\n      <td>2.67</td>\n      <td>4.77</td>\n      <td>-3.27</td>\n    </tr>\n    <tr>\n      <th>2023-12-31</th>\n      <td>-0.73</td>\n      <td>0.07</td>\n      <td>-8.50</td>\n      <td>10.77</td>\n      <td>99.63</td>\n      <td>4.80</td>\n      <td>87.50</td>\n      <td>87.37</td>\n      <td>-0.51</td>\n      <td>5.25</td>\n      <td>...</td>\n      <td>5.57</td>\n      <td>9.97</td>\n      <td>10.87</td>\n      <td>12.00</td>\n      <td>4.70</td>\n      <td>-2.73</td>\n      <td>-1.10</td>\n      <td>1.83</td>\n      <td>2.83</td>\n      <td>-3.41</td>\n    </tr>\n    <tr>\n      <th>2024-03-31</th>\n      <td>-1.93</td>\n      <td>0.19</td>\n      <td>-19.40</td>\n      <td>10.03</td>\n      <td>98.97</td>\n      <td>5.30</td>\n      <td>89.13</td>\n      <td>88.23</td>\n      <td>-2.44</td>\n      <td>5.30</td>\n      <td>...</td>\n      <td>5.47</td>\n      <td>9.77</td>\n      <td>11.43</td>\n      <td>12.73</td>\n      <td>5.87</td>\n      <td>7.05</td>\n      <td>-1.57</td>\n      <td>1.27</td>\n      <td>4.29</td>\n      <td>-3.44</td>\n    </tr>\n    <tr>\n      <th>2024-06-30</th>\n      <td>-4.23</td>\n      <td>0.22</td>\n      <td>-19.00</td>\n      <td>9.23</td>\n      <td>98.77</td>\n      <td>4.50</td>\n      <td>86.93</td>\n      <td>84.87</td>\n      <td>-3.20</td>\n      <td>5.00</td>\n      <td>...</td>\n      <td>5.20</td>\n      <td>9.50</td>\n      <td>11.40</td>\n      <td>11.77</td>\n      <td>4.37</td>\n      <td>11.40</td>\n      <td>-4.53</td>\n      <td>0.10</td>\n      <td>4.50</td>\n      <td>-3.46</td>\n    </tr>\n    <tr>\n      <th>2024-09-30</th>\n      <td>-5.70</td>\n      <td>0.13</td>\n      <td>-17.10</td>\n      <td>8.43</td>\n      <td>98.30</td>\n      <td>4.20</td>\n      <td>85.83</td>\n      <td>84.37</td>\n      <td>-0.75</td>\n      <td>4.80</td>\n      <td>...</td>\n      <td>5.17</td>\n      <td>8.97</td>\n      <td>10.87</td>\n      <td>10.53</td>\n      <td>2.20</td>\n      <td>4.20</td>\n      <td>-3.30</td>\n      <td>-0.07</td>\n      <td>4.23</td>\n      <td>-3.48</td>\n    </tr>\n    <tr>\n      <th>2024-12-31</th>\n      <td>-6.00</td>\n      <td>0.34</td>\n      <td>-12.90</td>\n      <td>7.77</td>\n      <td>98.85</td>\n      <td>4.40</td>\n      <td>86.50</td>\n      <td>84.27</td>\n      <td>13.59</td>\n      <td>5.00</td>\n      <td>...</td>\n      <td>5.03</td>\n      <td>9.40</td>\n      <td>10.60</td>\n      <td>10.00</td>\n      <td>1.50</td>\n      <td>8.37</td>\n      <td>-2.77</td>\n      <td>-0.33</td>\n      <td>6.00</td>\n      <td>-3.39</td>\n    </tr>\n  </tbody>\n</table>\n<p>32 rows × 109 columns</p>\n</div>"
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 做一些简单的指标衍生\n",
    "data_shift1 = data_model_sample.shift(1)\n",
    "data_shift1.columns = [f'{x}_lag1' for x in data_shift1.columns]\n",
    "data_shift2 = data_model_sample.shift(2)\n",
    "data_shift2.columns = [f'{x}_lag2' for x in data_shift2.columns]\n",
    "data_shift3 = data_model_sample.shift(3)\n",
    "data_shift3.columns = [f'{x}_lag3' for x in data_shift3.columns]\n",
    "data_shift4 = data_model_sample.shift(4)\n",
    "data_shift4.columns = [f'{x}_lag4' for x in data_shift4.columns]\n",
    "data_train = pd.concat([data_model_sample, data_shift1, data_shift2, data_shift3, data_shift4], axis=1)\n",
    "data_train = data_train.ffill().bfill().loc['2017-01-01':]\n",
    "data_train.drop('NPL', axis=1, inplace=True)\n",
    "data_train"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:45:11.591010Z",
     "start_time": "2025-02-19T01:45:11.550976Z"
    }
   },
   "id": "a8e1a1c211c72d8a",
   "execution_count": 14
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 单指标筛选"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "aeb49b8131ab339b"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "特征筛选完成，筛选前共108，筛选后共47个\n",
      "特征最低标准要求：\n",
      " - 缺失率不超过0.5\n",
      " - 连续缺失值不超过5个\n",
      " - 指标集中度不超过0.8\n",
      " - 单指标与目标指标相关系数不低于0.05\n",
      " - 单指标与目标指标之间的p值不超过0.05\n",
      " - 基准指标不在排除列表中\n"
     ]
    }
   ],
   "source": [
    "from rmtools.stats.stats import stats_avg_cv, stats_concn, stats_cmiss, stats_ycorr, stats_px_reg\n",
    "\n",
    "xs = [x for x in data_train.columns if x != 'NPL_logit']\n",
    "y = 'NPL_logit'\n",
    "max_miss = 0.5  # 缺失率阈值\n",
    "max_cmiss = 5  # 连续缺失值阈值\n",
    "max_concn = 0.8  # 指标集中度阈值\n",
    "min_corr = 0.05  # 相关系数阈值\n",
    "max_pvalue = 0.05  # p值阈值\n",
    "\n",
    "data_basic = stats_avg_cv(data_train, xs)\n",
    "data_concn = stats_concn(data_train, xs)\n",
    "data_cmiss = stats_cmiss(data_train, xs)\n",
    "data_ycorr = stats_ycorr(data_train, xs, y, 'pearson')\n",
    "data_px = stats_px_reg(data_train, xs, y)\n",
    "\n",
    "data_stats = pd.concat([data_basic, data_concn, data_cmiss, data_ycorr, data_px], axis=1)\n",
    "data_stats['is_above_miss'] = data_stats['missing'] > max_miss  # 缺失率是否超过阈值\n",
    "data_stats['is_above_cmiss'] = data_stats['cmiss'] > max_cmiss  # 连续缺失值是否超过阈值\n",
    "data_stats['is_above_concn'] = data_stats['pvalue'] > max_concn  # 集中度是否超过阈值\n",
    "data_stats['is_below_corr'] = np.abs(data_stats['corr']) < min_corr  # 相关系数是否超过阈值\n",
    "data_stats['is_above_pvalue'] = data_stats['pvalue'] > max_pvalue  # p值是否超过阈值\n",
    "\n",
    "data_stats['is_selected'] = ~data_stats[['is_above_miss', 'is_above_cmiss', 'is_above_concn',\n",
    "                                         'is_below_corr', 'is_above_pvalue']].any(axis=1)\n",
    "list_kept_xs = data_stats.loc[data_stats['is_selected']].index.tolist()\n",
    "info_filter = (f\"特征筛选完成，筛选前共{len(xs)}，筛选后共{len(list_kept_xs)}个\\n\"\n",
    "               f\"特征最低标准要求：\\n\"\n",
    "               f\" - 缺失率不超过{max_miss}\\n\"\n",
    "               f\" - 连续缺失值不超过{max_cmiss}个\\n\"\n",
    "               f\" - 指标集中度不超过{max_concn}\\n\"\n",
    "               f\" - 单指标与目标指标相关系数不低于{min_corr}\\n\"\n",
    "               f\" - 单指标与目标指标之间的p值不超过{max_pvalue}\\n\"\n",
    "               f\" - 基准指标不在排除列表中\")\n",
    "print(info_filter)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:45:11.976296Z",
     "start_time": "2025-02-19T01:45:11.600089Z"
    }
   },
   "id": "52d6d3396e4bce62",
   "execution_count": 15
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 多指标组合筛选"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "19c5899a5ca19d5a"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "特征组合....: 100%|██████████| 1729600/1729600 [10:44<00:00, 2684.21it/s]  "
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "特征组合分析完成，筛选前共1729600个组合，筛选后共38123个\n",
      "特征组合最低标准要求：\n",
      " - 指标组合相关系数不超过0.7\n",
      " - 指标组合vif不超过10\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "from rmtools.utils.gen_xslist import gen_xslist\n",
    "\n",
    "list_xs_comb = gen_xslist(xs=list_kept_xs, n_xs=range(2, 6))\n",
    "data_comb: pd.DataFrame = pd.DataFrame(columns=['xs', 'corr', 'vif'])\n",
    "data_base: pd.DataFrame = data_train.corr()\n",
    "\n",
    "max_corr: float = 0.7\n",
    "max_vif: float = 10\n",
    "\n",
    "for xs in tqdm(list_xs_comb, desc='特征组合....'):\n",
    "    # 如果含NPL原始指标，排除，NPL作为入模指标不太合适\n",
    "    if any([x.startswith('NPL_lag') for x in xs]):\n",
    "        continue\n",
    "    \n",
    "    # 如果只有两个指标，其中一个跟NPL有关，排除\n",
    "    if len(xs) == 2 and any([x.startswith('NPL') for x in xs]):\n",
    "        continue\n",
    "    \n",
    "    _corr = stats_max_corr(data_base, xs, is_corrdata=True)\n",
    "    if _corr >= max_corr:\n",
    "        _vif = np.nan\n",
    "    else:\n",
    "        _vif = stats_max_vif(data_train, xs)\n",
    "        if _vif >= max_vif:\n",
    "            pass\n",
    "        else:\n",
    "            data_comb.loc[len(data_comb)] = [xs, _corr, _vif]\n",
    "\n",
    "data_comb['is_above_corr'] = data_comb['corr'] >= max_corr  # 相关系数是否超过阈值\n",
    "data_comb['is_above_vif'] = data_comb['vif'] >= max_vif  # vif是否超过阈值\n",
    "data_comb['is_selected'] = ~data_comb[['is_above_corr', 'is_above_vif']].any(axis=1)\n",
    "list_kept_xs_comb = data_comb.loc[data_comb['is_selected'], 'xs'].tolist()\n",
    "\n",
    "info_comb = (f\"特征组合分析完成，筛选前共{len(list_xs_comb)}个组合，筛选后共{len(list_kept_xs_comb)}个\\n\"\n",
    "             f\"特征组合最低标准要求：\\n\"\n",
    "             f\" - 指标组合相关系数不超过{max_corr}\\n\"\n",
    "             f\" - 指标组合vif不超过{max_vif}\")\n",
    "print(info_comb)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T02:01:58.384976Z",
     "start_time": "2025-02-19T01:51:12.648960Z"
    }
   },
   "id": "2256d18bb528f7fc",
   "execution_count": 18
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 模型训练"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "65b936d2df4b4efb"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "run model: 100%|██████████| 38123/38123 [06:07<00:00, 103.78it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "模型训练完成，共计训练38123个组合，筛选后共703个\n",
      "模型最低标准要求：\n",
      " - 模型p值不超过0.05\n",
      " - 指标p值不超过0.05\n",
      " - r2不低于0.4\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "\n",
    "def one_model(indata: pd.DataFrame, xs: list[str], y: str):\n",
    "    x_sample = indata[xs].fillna(0)\n",
    "    x_sample = sm.add_constant(x_sample)\n",
    "    y_sample = indata[y]\n",
    "\n",
    "    model = sm.OLS(y_sample, x_sample, missing='drop')\n",
    "    model_fit = model.fit()\n",
    "    p_list = model_fit.pvalues.iloc[1:].to_dict()\n",
    "    p_value = model_fit.pvalues.iloc[1:].max()\n",
    "    p_model = model_fit.f_pvalue\n",
    "    r2 = model_fit.rsquared\n",
    "    mse = mean_squared_error(model_fit.predict(), y_sample)\n",
    "    coef = model_fit.params.to_dict()\n",
    "\n",
    "    dict_p = {f'p_{x}': y for x, y in p_list.items()}\n",
    "    dict_coef = {f'coef_{x}': y for x, y in coef.items()}\n",
    "    return model_fit, pd.DataFrame([{'xs': xs,\n",
    "                                     'p_value': p_value,\n",
    "                                     'p_model': p_model,\n",
    "                                     'r2': r2,\n",
    "                                     'mse_model': mse,\n",
    "                                     **dict_p,\n",
    "                                     **dict_coef}])\n",
    "\n",
    "\n",
    "def all_stats(indata: pd.DataFrame, y: str, list_xs: list[str]):\n",
    "    \"\"\" 所有统计指标 \"\"\"\n",
    "    data_stats = pd.DataFrame()\n",
    "    list_model = []\n",
    "    for xs in tqdm(list_xs, desc='run model'):\n",
    "        _model, _stat = one_model(indata, xs, y)\n",
    "        data_stats = pd.concat([data_stats, _stat], axis=0)\n",
    "        list_model.append(_model)\n",
    "\n",
    "    list_col1 = ['xs', 'p_value', 'p_model', 'r2', 'mse_model']\n",
    "    list_col2 = list(\n",
    "            set([x.removeprefix('coef_').removeprefix('p_') for x in data_stats.columns]).difference(set(list_col1)))\n",
    "    list_col2.sort()\n",
    "    list_col3 = list_col1 + ['coef_const']\n",
    "    for x in list_col2:\n",
    "        if x not in ['const', 'model', 'value']:\n",
    "            list_col3.extend([f'coef_{x}', f'p_{x}'])\n",
    "\n",
    "    data_stats = data_stats[list_col3]\n",
    "    data_stats.set_index('xs', inplace=True)\n",
    "    return data_stats, list_model\n",
    "\n",
    "\n",
    "max_pmodel = 0.05  # 模型p值阈值\n",
    "max_pvalue = 0.05  # 单指标p值阈值\n",
    "min_r2 = 0.4  # r2阈值\n",
    "\n",
    "# ols = all_stats(data_train, y, list_kept_xs_comb)\n",
    "data_models, list_models = all_stats(data_train, y, list_kept_xs_comb)\n",
    "data_models.insert(4, 'is_above_pvalue', data_models['p_value'] > max_pvalue)  # p值是否超过阈值\n",
    "data_models.insert(5, 'is_above_pmodel', data_models['p_model'] > max_pmodel)  # 模型p值是否超过阈值\n",
    "data_models.insert(6, 'is_below_r2', data_models['r2'] < min_r2)  # r2是否低于阈值\n",
    "data_models.insert(7, 'is_qualified',\n",
    "                   ~data_models[['is_above_pvalue', 'is_above_pmodel', 'is_below_r2']].any(axis=1))\n",
    "info_models = (f\"模型训练完成，共计训练{len(list_models)}个组合，筛选后共{data_models['is_qualified'].sum()}个\\n\"\n",
    "               f\"模型最低标准要求：\\n\"\n",
    "               f\" - 模型p值不超过{max_pmodel}\\n\"\n",
    "               f\" - 指标p值不超过{max_pvalue}\\n\"\n",
    "               f\" - r2不低于{min_r2}\")\n",
    "print(info_models)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T02:16:11.387910Z",
     "start_time": "2025-02-19T02:10:04.011395Z"
    }
   },
   "id": "84a6d26ab0c08b07",
   "execution_count": 21
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "data_models.to_clipboard()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T02:16:52.957581Z",
     "start_time": "2025-02-19T02:16:50.177442Z"
    }
   },
   "id": "fba05d2324e55e0a",
   "execution_count": 22
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# data_models_qualified = data_models[\n",
    "#     ~data_models.index.astype(str).str.contains('NPL_lag') & data_models['is_qualified']]\n",
    "# data_models_qualified = data_models_qualified[\n",
    "#     data_models_qualified.index.astype(str).str.count('_lag') <= data_models_qualified.index.astype(str).str.count(',')]\n",
    "\n",
    "data_models_qualified = data_models[data_models['is_qualified']]\n",
    "\n",
    "\n",
    "def _is_sml(xlist: list[str]) -> bool:\n",
    "    newset = [x.split('_lag')[0] for x in xlist]\n",
    "    return len(set(newset)) == len(xlist)\n",
    "\n",
    "\n",
    "data_models_qualified = data_models_qualified[data_models_qualified.index.map(lambda x: _is_sml(x))]\n",
    "data_models_qualified.dropna(axis=1, how='all', inplace=True)\n",
    "data_models_qualified.to_clipboard()\n",
    "data_models_qualified"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:46:00.702831Z",
     "start_time": "2025-02-19T01:46:00.700831Z"
    }
   },
   "id": "830e7c1f62979c10",
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 模块3：生成压力情景值"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "dc7dae63e190c4fc"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "data_std = data_sample.std()\n",
    "data_corr = data_std.copy()\n",
    "data_corr.values[:] = 1\n",
    "\n",
    "\n",
    "def _gendata(data_in):\n",
    "    data_in['NPL_logit'] = np.log(data_in['NPL'] / (1 - data_in['NPL']))\n",
    "    data_shift1 = data_in.shift(1)\n",
    "    data_shift1.columns = [f'{x}_lag1' for x in data_shift1.columns]\n",
    "    data_shift2 = data_in.shift(2)\n",
    "    data_shift2.columns = [f'{x}_lag2' for x in data_shift2.columns]\n",
    "    data_shift3 = data_in.shift(3)\n",
    "    data_shift3.columns = [f'{x}_lag3' for x in data_shift3.columns]\n",
    "    data_shift4 = data_in.shift(4)\n",
    "    data_shift4.columns = [f'{x}_lag4' for x in data_shift4.columns]\n",
    "    data_train = pd.concat([data_in, data_shift1, data_shift2, data_shift3, data_shift4], axis=1)\n",
    "\n",
    "    return data_train\n",
    "\n",
    "\n",
    "def _stress_data(senr: int = 0):\n",
    "    list_senr = [0, 1, 1.5, 2]\n",
    "    data_inv_real_ = data_inv_real - data_std * data_corr * list_senr[senr]\n",
    "    data_stress = pd.concat([data_sample, data_inv_real_])\n",
    "    return _gendata(data_stress).loc['2024-01-01':]\n",
    "\n",
    "\n",
    "def _get_coef(model_ver: int):\n",
    "    xvars = data_models_qualified.index[model_ver]\n",
    "    coefs = data_models_qualified.iloc[model_ver][[f'coef_{x}' for x in xvars]]\n",
    "    const = data_models_qualified.iloc[model_ver]['coef_const']\n",
    "    return xvars, coefs, const\n",
    "\n",
    "\n",
    "def _stress_result(ver: int = 0):\n",
    "    xvars, coefs, const = _get_coef(ver)\n",
    "\n",
    "    xvars2 = list(set(xvars).union({'NPL_lag1', 'NPL_lag2', 'NPL_lag3', 'NPL_lag4',\n",
    "                                    'NPL_logit_lag1', 'NPL_logit_lag2', 'NPL_logit_lag3', 'NPL_logit_lag4'}))\n",
    "\n",
    "    data_result = pd.DataFrame()\n",
    "    for i in range(4):\n",
    "        data_stress = _stress_data(senr=i)[xvars2]\n",
    "        data_stress['NPL_logit_pred'] = data_stress[xvars].dot(coefs.values) + const\n",
    "\n",
    "        for _ in range(12):\n",
    "            data_stress['NPL_logit_lag1'] = data_stress['NPL_logit_lag1'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(1)).astype(float)\n",
    "            data_stress['NPL_logit_lag2'] = data_stress['NPL_logit_lag2'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(2)).astype(float)\n",
    "            data_stress['NPL_logit_lag3'] = data_stress['NPL_logit_lag3'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(3)).astype(float)\n",
    "            data_stress['NPL_logit_lag4'] = data_stress['NPL_logit_lag4'].combine_first(\n",
    "                    data_stress['NPL_logit_pred'].shift(4)).astype(float)\n",
    "            data_stress['NPL_lag1'] = np.exp(data_stress['NPL_logit_lag1']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag1']))\n",
    "            data_stress['NPL_lag2'] = np.exp(data_stress['NPL_logit_lag2']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag2']))\n",
    "            data_stress['NPL_lag3'] = np.exp(data_stress['NPL_logit_lag3']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag3']))\n",
    "            data_stress['NPL_lag4'] = np.exp(data_stress['NPL_logit_lag4']) / (\n",
    "                    1 + np.exp(data_stress['NPL_logit_lag4']))\n",
    "\n",
    "            data_stress['NPL_logit_pred'] = (data_stress[xvars].dot(coefs.values) + const).astype(float)\n",
    "\n",
    "        data_stress[f'NPL_logit_{i}'] = data_stress['NPL_logit_pred']\n",
    "        data_stress[f'NPL_pred_{i}'] = np.exp(data_stress[f'NPL_logit_{i}']) / (\n",
    "                1 + np.exp(data_stress[f'NPL_logit_{i}']))\n",
    "        if i == 0:\n",
    "            data_result = data_stress[[f'NPL_logit_{i}', f'NPL_pred_{i}']].copy()\n",
    "        else:\n",
    "            data_result = pd.concat([data_result, data_stress[[f'NPL_logit_{i}', f'NPL_pred_{i}']]], axis=1)\n",
    "    return data_result\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:46:00.707809Z",
     "start_time": "2025-02-19T01:46:00.704812Z"
    }
   },
   "id": "b51124c024f8435f",
   "execution_count": null
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "list_rst = []\n",
    "for i in range(len(data_models_qualified)):\n",
    "    data_stress = _stress_result(i)\n",
    "    x01 = data_stress.loc['2025-12-31', 'NPL_pred_0']\n",
    "    x02 = data_stress.loc['2025-12-31', 'NPL_pred_1']\n",
    "    x03 = data_stress.loc['2025-12-31', 'NPL_pred_2']\n",
    "    x04 = data_stress.loc['2025-12-31', 'NPL_pred_3']\n",
    "    x11 = data_stress.loc['2026-12-31', 'NPL_pred_0']\n",
    "    x12 = data_stress.loc['2026-12-31', 'NPL_pred_1']\n",
    "    x13 = data_stress.loc['2026-12-31', 'NPL_pred_2']\n",
    "    x14 = data_stress.loc['2026-12-31', 'NPL_pred_3']\n",
    "    x21 = data_stress.loc['2027-12-31', 'NPL_pred_0']\n",
    "    x22 = data_stress.loc['2027-12-31', 'NPL_pred_1']\n",
    "    x23 = data_stress.loc['2027-12-31', 'NPL_pred_2']\n",
    "    x24 = data_stress.loc['2027-12-31', 'NPL_pred_3']\n",
    "    list_rst.append([i, x01, x02, x03, x04, x11, x12, x13, x14, x21, x22, x23, x24])\n",
    "\n",
    "data_stress_summary = pd.DataFrame(list_rst,\n",
    "                                   columns=['ver', 'x01', 'x02', 'x03', 'x04', 'x11',\n",
    "                                            'x12', 'x13', 'x14', 'x21', 'x22', 'x23', 'x24'])\n",
    "data_stress_summary.to_clipboard(index=False)\n",
    "data_stress_summary"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-19T01:46:00.710807Z",
     "start_time": "2025-02-19T01:46:00.709807Z"
    }
   },
   "id": "cda9872ea73ba6b8",
   "execution_count": null
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
